OmniAICreator/Qiita-1.07M huggingface dataset:
AWS Networking Roadshow Gameday 2024に参加しました！

# はじめに
2024年9月3日に開催された「AWS Networking Roadshow Gameday 2024」に弊社から3名参加してきました！

私はこれまでGamedayに参加したことがなく、どのようなイベントなのか興味を持っていました。そんな矢先にGamedayの告知があり、参加してみようと思い手を挙げました:raising_hand:

また、実務ではネットワーク関連の経験があまりなかったためこの機会にネットワークに関する知識を深めたいと考え、参加しましたので当日の様子や感想について書かせていただきます！

# GameDayとは
AWSが主催しているイベントで、参加者が実際のビジネスシナリオに基づいた課題に取り組むことができます。このイベントには、ネットワークに関するテーマに限らず、セキュリティやDevOpsなどさまざまなテーマがあります。

GameDayはハンズオンを中心としたゲーム形式で進行し、参加者は与えられた課題に応じて適切なAWSリソースを構築することでポイントを獲得します。制限時間内に獲得したポイントが一番高いチームが優勝です。課題には、ボーナスポイントが得られるものや、迅速に対処しないと減点されるものもあり、参加者の問題解決能力や迅速な対応力が試されます。:thinking:

https://aws.amazon.com/jp/gameday/


# AWS Networking Roadshow Gameday 2024
今回のGamedayは、ネットワークがテーマとなっており、参加者は架空の会社の新入社員としてAWSを活用し、さまざまな課題に挑戦します。難易度は高めに設定されており、実践的なスキルと深い理解が試される内容でした。

また、今回は異なる会社のメンバーでチームを組み、チーム対抗戦で競い合いました。そのため、チーム内での協力・コラボレーションがより重要になるイベントでした。


# 結果
メンバーで協力して一つずつ課題を進めていった結果・・・
なんと**優勝**することができました！！！:trophy::sparkles:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3333262/c3630603-fe40-fb03-ff5b-03e3e0c1116b.png)

私たちは、最初からチームで課題を分担することはせず、全員でその課題に取り組み、それぞれが体系的に勉強しながら課題を解き進めていきました。

そのため、途中まで上位にも食い込めなかったのですが、制限時間ギリギリのところで課題を全て解き終え、見事逆転優勝することができました！同じチームの方にも感謝です！:sob:

# このGameDayを通して学んだこと
私がこのGameDayで特に学んだのは、ネットワーク構成の初期設計が非常に重要であるということです。後の拡張や新たな課題に対処するためには、初期の段階での設計が大きな影響を与えると実感しました。

私たちは、最初のネットワーク構成を構築する際、後々新たな要素が加わる可能性を考慮して設計を行いました。しかし、その後さらに複雑な構成が求められる課題が出題されたため、一部の構成を変更する必要がありました。

もし、最初の構成を単純なものにしていたら、後々の対応が難しくなっていたと思います。

# GameDayに参加してみて
Gamedayに参加してみて、難易度は確かに高かったものの、全く手も足も出ないほどではありませんでした。わからないことがあっても、チームメンバーに教えてもらいながら楽しく勉強することができました:relaxed:

また、実務ではあまり触れる機会のないAWSのサービスを使用することができ、貴重な体験を積むことができました。

懇親会では、Top EngineersやAll Certifications Engineersの方々やAWSのネットワークサービスの開発者の方々と話す機会があり、とても有意義な時間を過ごすことができました。

# 最後に
今回初めてGameDayに参加してみて、ハンズオン形式で楽しく勉強することができ、とても良い機会でした。

また、他社のAWSエンジニアの方々と交流することができ、モチベーションが上がりました。早速、AWSのネットワーク系の資格を取ろうと思います！:muscle:

GameDayは難易度優しめのものもあるそうなので、
参加したことがない方はチャレンジで行ってみるのも良いと思います。

またGameDayがあったら参加したいと思います！！:fist:

# 弊社では一緒に働く仲間を募集中です:trophy:
現在、様々な職種を募集しております。
カジュアル面談も可能ですので、ご連絡お待ちしております！

募集内容等詳細は、是非採用サイトをご確認ください。
[https://engineer.po-holdings.co.jp/](https://engineer.po-holdings.co.jp/)
SharePointOnlineメモ

SharePointOnlineの自分用メモ

# タイトルエリアを消す
Home.aspxをコピーすれば、タイトルエリアが消えるが、この場合、SNSパーツ（「いいね」等）も消えてしまう。
タイトルエリアだけ消したい場合、PowerShellでLayoutType をHome にする。
```
PS> Connect-PnPOnline -Url "https://xxxx.sharepoint.com/sites/HogeHoge"
Set-PnPClientSidePage -Identity "Target.aspx" -LayoutType "Home"
```

# Webパーツの遅延読み込み回避
通常、Webパーツは遅延読み込みされるため、ページ内リンクが無効なことがある。
その場合の対策の１つ。
[SharePointOnlineでWebパーツの遅延読み込みを回避する](https://qiita.com/hrtk91/items/e6d48959fb840ba884c2)

# 「戻る」とCSS読み込み順
ブラウザの「戻る」を行った場合、通常CSSとWebパーツCSSの読み込み順がおかしくなることがある。
```!important``` で対応する。

# target="_blank" が効かない
SPFx内の Aタグの```target="_blank"``` だが、SharePoint内ページのリンクの場合、別ウインドウとならないことがある。
Aタグに以下を追加して対応する。
```
data-interception="off"
```
https://sharepoint.stackexchange.com/questions/279133/target-blank-not-working-in-a-tag-sharepoint-online
https://julieturner.net/post/spfx-anchor-tags/
Supabaseのリージョン変更手順：新規プロジェクト作成による対応

## 追記
この記事を書き終えた後に、公式ドキュメントでプロジェクトの移行手順が案内されているのを認識しました。

[Migrating and Upgrading Projects | Supabase Docs](https://supabase.com/docs/guides/platform/migrating-and-upgrading-projects)

基本的には公式ドキュメントを参照していただくのが望ましいかと思います。
（一応、公式ドキュメントは情報が多く、かつ手順も異なりますので、簡易版ということで本記事はそのまま残しておこうかと思います。）

## はじめに

WEBアプリのパフォーマンスを改善するために、Supabaseのリージョンを変更したいと思いました。しかし、Supabaseではプロジェクトのリージョンを直接変更することができないようです[^1]。

そこで、新しいプロジェクトを作成してデータや設定を移行することでリージョンを変更しました。この記事では、その手順を備忘録として記載します。

有料プランであればバックアップ機能が提供されていますが、私は無料プランを利用しているため、`psql`コマンドを使用してバックアップを取得する方法を採用しました。

[^1]: [Change Project Region · supabase · Discussion #16341](https://github.com/orgs/supabase/discussions/16341)

## 手順概要

1. 本番DBのバックアップ
2. 新規プロジェクトの作成
3. 新規プロジェクトの設定
4. 新規プロジェクトへのデータ流し込み
5. ローカルから新規プロジェクトへ接続してテスト
6. 本番環境を新規プロジェクトに接続してテスト
7. 古いプロジェクトの整理

## 詳細手順

### 1. 本番DBのバックアップ

#### DB接続のテスト

まず、本番DBへの接続をテストします。

```bash
$ psql -h aws-0-ap-northeast-1.pooler.supabase.com -p 6543 -d postgres -U postgres.xxxxxxxxxxxxxxxx
```

接続情報の確認とdatabase passwordのリセットは、Supabaseのダッシュボードから行えます。
`Dashboard > Settings > Database`で確認できます。

接続できたら `\q` コマンドで抜けます。

#### DBのバックアップ

次に、`pg_dump`コマンドを使用してバックアップを取得します。

```bash
$ pg_dump -h aws-0-ap-northeast-1.pooler.supabase.com -p 6543 -d postgres -U postgres.xxxxxxxxxxxxxxxx > temp/supabase_backup.sql
```

### 2. 新規プロジェクトの作成

Supabaseのダッシュボードから新規プロジェクトを作成します。今回は`us-east-2(Ohio)`リージョンを選択しました。

### 3. 新規プロジェクトの設定

新規プロジェクトの設定を行います。以下の項目について、元のプロジェクトと同じ設定を行います。

- Authentication
- SMTP
- Email Templates
- URL Configuration

### 4. 新規プロジェクトへのデータ流し込み

#### DB接続のテスト

新規プロジェクトのDBへの接続をテストします。

```bash
$ psql -h aws-0-us-east-2.pooler.supabase.com -p 6543 -d postgres -U postgres.yyyyyyyyyyyyyyyy
```

#### DBのバックアップのリストア

バックアップデータを新規プロジェクトにリストアします。

```bash
$ psql -h aws-0-us-east-2.pooler.supabase.com -p 6543 -d postgres -U postgres.yyyyyyyyyyyyyyyy < temp/supabase_backup.sql
```

### 5. ローカルから新規Supabaseへ接続テスト

ローカル環境の`.env`ファイルを更新し、新規プロジェクトへの接続をテストします。

```env
SUPABASE_DB_PASSWORD=xxxxxxxxxxxxxxxx
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
NEXT_PUBLIC_SUPABASE_URL=https://xxxxxxxxxxxxxxxxxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```

### 6. 本番環境を新規Supabaseに接続してテスト

本番環境の設定を更新し、新規プロジェクトへの接続をテストします。環境に応じて設定方法が異なりますが、私の場合はNetlifyの環境変数を更新しました。

### 7. 古いプロジェクトの停止

最後に、古いプロジェクトを停止します。Supabaseダッシュボードの `Settings > General > Pause project` から行えます。

## 注意点とメモ

- デフォルトで生成されるテーブルが重複して、"already exists"のエラーが多数出ました。ただし、デフォルトで生成されている`auth`テーブル等も移行したかったので、このエラーは許容して実行しました。

- このアプリは、利用者が常時はいなかったため、この方法でなんとかなりました。実際に稼働していてデータが動き続けているシステムの場合は、メンテナンス時間を設けるか、一時的に新旧の同期を取るなど、別の手法が必要になると思われます。

- DatabaseのFunctions、Triggers、Extensions、およびRLSのPoliciesは、この方法で問題なく移行できました。ただし、Roleは移行できていない可能性があります（デフォルトのまま使用していたため、特に不都合はありませんでした）。

## おわりに

Supabaseのリージョン変更は直接行えませんが、新規プロジェクトを作成してデータを移行することで対応可能です。この記事が、同様の課題に直面している方の参考になれば幸いです。

## 参考資料

- [PostgreSQLのbackup, restore方法まとめ #PostgreSQL - Qiita](https://qiita.com/rice_american/items/ceae28dad13c3977e3a8)
- [Supabaseのバックアップをpsql経由で取る](https://zenn.dev/www_y/articles/a1e0c61a12b57c)
[Kotlin]インターバルタイマーを作ってみた！ part1[初心者]

<h2>はじめに</h2>
はじめまして！mAgmAです
今回からインターバルタイマーをKotlinで作成するまでの日記をつけていきます！
学習し始めて初めての自作アプリですが、持ち前の勢いと検索力で頑張ります！

<h2>作成しようと思った理由</h2>
今回インターバルタイマーを作ろうと思った理由ですが、僕は家で筋トレをしているんですね。
そのときに使えるタイマーが欲しいな、と思ったことがきっかけです。
じゃあ、自分で作っちゃえ！みたいなｗ

普段はpythonを使っていることが多いのですが、Androidアプリを作ろうとしたらよりKotlinで作ったほうがいいな、ということで学習も兼ねてやっていきます！

<h2>これからの工程</h2>
1,タイマー機能の作成、２つのタイマーを交互に指定回数作動できるようにする
2,タイマーの時間設定、レイアウトを作る（こらずにシンプルに）
3,細かな仕様の変更
4,完成！

こんな感じでやっていこうと思います！
※予定は未定

<h2>最後に</h2>
今回の日記は決意表明でした！
次回からプログラミングなど、内容の話を入れて日記をつけていこうと思います。
大体毎日投稿頑張れ自分！

ありがとうございました
学生のエンジニア長期インターンの見つけ方

## はじめに
僕自身がエンジニア長期インターンを探すのに苦労した経験から、自分が長期インターンを探すのに使ったサイトを共有したいと思います。

## 現在の自分のスペック
京都に住んでいる大学2回生。エンジニアの長期インターンに参加しているが、ポートフォリオがないです。

自分が新しい長期インターンを探した際に使っているサイトを書いてきます。
## おすすめのサイト

### Wantedly

https://wantedly.com

メリット
・募集を行っている企業の数が他のサイトに比べてかなり多い

デメリット
・応募したにも関わらず、返信がない場合がある

### ゼロワンインターン

https://01intern.com/


メリット
・名前の通り、何もない状態から始める人のためのサイトなので、プロフィールに記入することも、氏名、性別、住所、携帯電話番号、在籍学校名、学部、学科、卒業年度だけで、特別な実績なしで申し込むことが可能

・企業の返信率が、僕が申し込んだ中だと100%

デメリット
・企業の数が少ないため、自分の住んでいる場所からでも参加できる、京都にあるインターン、フルリモートインターンの数が少なかった

### インフラインターン

https://www.in-fra.jp/long-internship?gad_source=1&gclid=CjwKCAjw3P-2BhAEEiwA3yPhwD-E1qB5IMs6l7DueVc9OSMWW3wre4KHDjbh-WrhGfooMKRdQ797YhoCrIwQAvD_BwE

メリット
・いろいろな企業からスカウトが来る

・LINEでログインするとLINEのメッセージでスカウトやおすすめの企業などを教えてくれる

デメリット
・ゼロワンインターンと同じデメリットになりますが、企業の数が少ないため、自分の住んでいる場所からでも参加できる、京都にあるインターン、フルリモートインターンの数が少なかった

ポートフォリオがある人は、以下のサイトから探すのがおすすめだと思います。
僕自身はポートフォリオを持っておらず、使ったことがないため、説明は割愛させていただきます。

https://magic-spreadsheets.github.io/

## 最後に
最後まで読んでいただきありがとうございます。
自分がいろいろ長期インターンに応募して思ったのですが、ポートフォリオがなくても、長期インターンを見つけることは可能ですが、ポートフォリオは絶対にあった方がいいと思います。
[RDB] key

# 一覧

|大分類|||
|:--|:--|:--|
|キー|表(関係)中の行を一意に識別する|スーパーキー、候補キー、主キー|
|外部キー|別の表(関係)を参照し関連付ける||

|分類|||
|:--|:--|:--|
|スーパーキー|表(関係)中の行を一意に特定できる属性・属性の組<br>***1**: 表内に同一行がなければ、全ての属性がスーパーキーになり得る||
|候補キー|行を一意に識別できる属性によって構成されるスーパーキー<br>表(関係)中で複数<br>***2**: Exampleのスーパーキーでは``氏名``や``性別``が候補キーに該当しない|``一意制約``|
|主キー|データ管理上最も適切な候補キー<br>表(関係)中で1つ|``一意制約``<br>``NOT NULL制約``=``主キー制約``|
|代理キー|主キーに選ばれなかった候補キー|``一意制約``|
|外部キー|関連する表の候補キーを参照する属性・属性の組|``参照制約``|

``一意制約``: 重複が認められない
``NOT NULL制約``: NULLが認められない
``参照制約``: 外部キーの値が非参照表（外部キーによって参照される表）に存在することを保証

# Example
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/35360375-19d5-2706-e26d-1a0e5115f19c.png)

- 主キー：{社員番号、連番}
- 候補キー：{社員番号、連番}
　　　　　　{電話番号}
- スーパーキー：{社員番号、連番}
　　　　　　　　{社員番号、連番、氏名}
　　　　　　　　{社員番号、連番、氏名、性別}
　　　　　　　　・・・
　　　　　　　　{社員番号、連番、氏名、性別、電話番号、住所}   ←***1**

# Image
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/2c2ff1b2-8c9e-c9a8-d440-95d6f76ead7a.png)

# Appendix
|AA|BB|CC|
|---|---|---|
|**|**/&&|**|
||&&||
||&&||

``**``:タプル
``&&``:属性(アトリビュート)

# 参考リンク
- [主キー、候補キー、外部キー、スーパーキーなどのいろんなキーについて｜データベースの基礎](https://poppingcarp.com/various_key/)
- [令和2秋27](https://www.ap-siken.com/kakomon/02_aki/q27.html)
slidde


[slidde.co](https://slidde.co)

ウェブページを作成する際の最も一般的な問題は、毎回面倒なレイアウトとJavaScriptロジックを書かなければならないことです。しかし、それらはほとんど同じです。
私はコーディングをスタイリング（CSS）に限定しようとしています。スタイリングこそが、実際に各クライアント/ウェブページにカスタマイズするものです。

ドロップダウンやラジオボタンを使用してウェブページをスタイリングしようとすると、苦痛になります。":hover"などのセレクタを有効にすることで、スタイリングはほぼすべての要素に対して可能になります。
リモートリポジトリにpush済みの直前のコミットとローカルのステージにある修正(未コミット)を一つにまとめてpush

## 筆者が遭遇したシチュエーション（例）

ある機能追加をするタイミングでprettierの導入をしたが、prettier分のコミットと、機能追加のコミットを分けようと思った。

* 直前のコミット
    * ファイルAのprettier適用差分
* 現在の状況
    * ファイルBに処理追加。保存時prettierが適用され、両方の修正が混ざった状態になった
    * ファイルBのprettier分を直前のコミットに混ぜて、機能追加は別途コミットしたい

## 対応

本説明ではvscodeとコマンド両方の操作が混ざっているが、以下のように対応した

### 1.ファイルBを行単位でコミットする

vscodeのgit(ソース管理)の「変更」でファイルBを選択すると、左右で差分表示される。
右ペインの変更部分の左に

```
→
+
```
このようなボタンが出るので、prettierの変更行のみ「+」をクリックしてstageに移していく。
試してはいないが、調べたところコマンドの `git add -p` に相当する操作と思われる。
そうすると、変更分のみステージに上がる。
prettier分すべてステージに上げたらターミナルで下記実行する。

```
$ git commit --amend --no-edit
```

`--amend` オプションは直前のコミットに変更を追加し、`--no-edit` オプションはコミットメッセージをそのままにする。

vscodeの場合は、`cmd + shift + p` をして、`amend` と入力すると `Git: Commit Staged (Amend)` というのが出てきて、おそらくこれを選択すれば良さそう。（未検証)

そしたらローカルの直前のコミットに含めることができるので、以下コマンドで強制的にpushする。

```
$ git push --force-with-lease
```

prettier分のコミットをまとめてpushすることができた。
Snowflakeで各カラムのnull件数を取得するプロシージャを作成した

# 初めに
最近Snowflakeのスキーマにあるテーブルの中にnullのデータが存在するかを知りたかったので、取得するプロシージャを作成しました。
正確にはtry_to_timestamp(hoge, 'YYYY-MM-DD')している箇所があり、フォーマットが正しくないとnullになるため、そのフォーマットチェックをしたかったのが発端です。

# これがあるとどんなデータが表示されるの？
下記のように、対象のスキーマのテーブルのカラムに対してnullの件数が表示できます。
<img width="800" alt="スクリーンショット 2024-09-11 9.51.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3361865/981bf7bc-5c3d-6422-e82a-68ced15fbf4e.png">

# 作ったプロシージャはこれだ
```
-- 結果を保持するテーブル作成
CREATE OR REPLACE TABLE column_null_result (
    table_schema STRING,
    table_name STRING,
    column_name STRING,
    data_type STRING,
    null_count INTEGER
);
```

```
-- データベース：db_hoge
-- スキーマ：schema_huga
-- この二つの箇所を自身の環境に変更すればOK
CREATE OR REPLACE PROCEDURE column_null_info()
RETURNS STRING
LANGUAGE SQL
execute as caller
AS
declare
    res resultset default ( SELECT table_schema, table_name, column_name, data_type
                            FROM db_hoge.information_schema.columns 
                            WHERE table_schema = 'schema_huga'
                            );
    cur1 cursor for res;
    table_schema STRING;
    table_name STRING;
    column_name STRING;
    data_type STRING;
begin
    for raw_valiable in cur1 do
        table_schema := raw_valiable.table_schema;
        table_name := raw_valiable.table_name;
        column_name := raw_valiable.column_name;
        data_type := raw_valiable.data_type;

        EXECUTE IMMEDIATE '
            INSERT INTO column_null_result (table_schema, table_name, column_name, data_type, null_count)
                        SELECT ''' || table_schema || ''', ''' || table_name || ''', ''' || column_name || ''', ''' || data_type || ''', COUNT(*)
                        FROM schema_huga.' || table_name || '
                        WHERE "' || column_name || '" IS NULL;
        ';
                    
    end for;

    RETURN 'Success';
EXCEPTION
    WHEN OTHER THEN
        RETURN 'Error: ' || SQLERRM;
end;
```

```
-- プロシージャの実行
CALL column_null_info();
```

```
-- 結果のデータを表示
select * from column_null_result ;

-- タイムスタンプ型でnullが存在するカラムを表示
select * from column_null_result 
where null_count > 1
and data_type like 'TIMESTAMP%';
```

# ちょっとだけ解説
```
SELECT table_schema, table_name, column_name, data_type
                            FROM db_hoge.information_schema.columns 
                            WHERE table_schema = 'schema_huga'
```
この箇所で対象となるカラムの一覧を取得します。
そのため、where句に他の条件を付けて、初めからtimestamp型だけに絞ることもできます。

```
INSERT INTO column_null_result (table_schema, table_name, column_name, data_type, null_count)
                        SELECT ''' || table_schema || ''', ''' || table_name || ''', ''' || column_name || ''', ''' || data_type || ''', COUNT(*)
                        FROM schema_huga.' || table_name || '
                        WHERE "' || column_name || '" IS NULL;
```
この箇所でnullのデータ件数を取得しています。
もちろんnullでは無くて、0のデータ件数を取得したいのであれば、where句を書き換えればOK。

# 今後の課題
- 1レコードinsertするのに500msくらいかかっています。そのためテーブルやカラム数が多いと時間がかかります（=費用がかかる）。
- 上記対応としてはselectの結果は別で変数に覚えさせて、数10件〜数100件に1回insertするとかにしようと思います。
- 合わせて単純な件数もselectした結果に表示されるとデータとして使い勝手が良いなと感じたので、それも入れたいですね。
TypeScript経験者のためのGASの開発環境構築

先日Google Apps Script (GAS)を初めて触ったのですが 、開発環境はかなり不便な部分がったのでTypeScriptで書くためにやった過程のメモ

## GASの不便さ

GASは拡張機能 => App Scriptから標準のオンラインエディタで直接コードを書くことができますが、エンジニア視点だと大分不便です

### 1. Git管理ができない
   Git扱えないので毎回デプロイして確認みたいな手間が発生します
### 2. VSCodeが使えない
   VSCodeじゃないので全置換すらだいぶめんどくさい。シンタックスもない、、
### 3. 型がない
   補完は一応出ますが、やっぱり型が保証されてないので書きにくいです


## 必要なツールのインストール

まず、GASをTypeScriptで書くために必要なツールをインストールしましょう。以下の2つのパッケージが必要です。

1. **google/clasp**  

   claspを使うとローカルでVSCodeで開発したコードをそのまま連携できるので非常に便利です

   ```bash
   npm install -g @google/clasp
   ```

2. **@types/google-apps-script**  

   これを使うとGASの関数やライブラリを補完してくれます

   ```bash
   npm install @types/google-apps-script
   ```


## TypeScriptとGASの互換性問題を解決

clasp/typescriptを単純に使うと、ES6モジュール（`import`や`export`）に対応していないので、TypeScriptのコードそのまま使うことができません。
ですが、**それさえ解決してしまえばTypeScriptと全く同じように書けます**

**exportとimportの行をbuildしたjsからsedで消してしまえばいいのです**
```
sed -i '' 's/export //g' 
sed -i '' '/import/d'
```

## 実際に書いてみる

ディレクトリ構成は以下のとおりです

```

├─ src
|   ┗ index.ts
├─ .clasp.json.template
├─ .gitignore
├─ package-lock.json
├─ package.json
└─ tsconfig.json
```


```json:package.json
{
  "name": "gas-ts-clasp-esbuild-template",
  "version": "1.0.0",
  "description": "",
  "type": "module",
  "main": "index.js",
  "scripts": {
    "type-check": "tsc --noEmit",
    "build": "rm -rf dist && tsc -p tsconfig.json && cp src/appsscript.json dist/appsscript.json && sed -i '' 's/export //g' dist/**/*.js dist/**/**/*.js && sed -i '' '/import/d' dist/**/*.js dist/**/**/*.js",
    "push": "clasp push",
    "open": "clasp open",
    "deploy": "npm run build && npm run push"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "volta": {
    "node": "20.10.0"
  },
  "devDependencies": {
    "@google/clasp": "^2.4.2",
    "@types/google-apps-script": "^1.0.82",
    "clasp": "^1.0.0",
    "esbuild": "^0.20.1",
    "esbuild-gas-plugin": "^0.8.0",
    "typescript": "^5.3.3"
  }
}
```

```json:tsconfig.ts
{
  "compilerOptions": {
    "target": "es2016",
    "experimentalDecorators": true,
    "module": "ES2022",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "outDir": "./dist",
    "rootDir": "./src"
  },
  "include": ["./src/**/*.ts"]
}

```

この状態でindex.tsにTypeScriptのコードを書いてbuild & deployすることでGASに反映できます
package.jsonのscriptを見てもらえればわかりますが、distを作成してそのまま上げてます
```
npm run deploy
```


## さいごに

勘違いして欲しくないのがGAS自体はめちゃくちゃ便利でマジでなんでもできます。
自分も「エクセルのマクロみたいなもんやろｗｗｗｗ」程度に思って舐めてましたが、スプシの管理はもちろんのこと、使い方によっては「インフラ代のかからないバックエンド/DB」にもすることができます。

また、**クリーンアーキテクチャで書くことも可能**です
これはまた次の記事で紹介します！

追記：書きました
https://qiita.com/p3033119/items/b0d384472b73fd18266d
【AWS】0→1プロダクトにおけるアプリケーションデリバリー

## はじめに
　AWS Summit2024の[AWS コンテナサービスから考える安全なアプリケーションデリバリー(AWS-34)](https://www.youtube.com/watch?v=3Zin5h6lJXs)を受講しました。その内容を元に、現在私が携わっているプロダクトでどのように活用できるかを考えます。

## 担当プロダクト
　現在私が携わっているのは社内の営業向けに求人広告の作成を手助けするプロダクトです。
　今年の夏にリリースしたばかりで、プロダクトとしてはまだ0→1のフェーズであり、一部の営業さんに使って貰いながらニーズを検証し、日々機能の追加や修正を行なっています。そのため開発チームも小さく、実際にコーディングを行なっているのは私を含め２名です。

　フロントエンドにNuxt.jsを使用しており、ECSにデプロイしているため本セッションの内容を今後の開発にどのように活用できるか考えたいと思います

:::note info
Note：担当プロダクト
- 社内向け
- 0→1フェーズ
- 小さく作って検証
- 小さな開発チーム
:::

## 安全なアプリケーションデリバリーとは

ずばり、「障害などが発生した際の影響を最小限に抑えるデリバリー」のこと。

:::note info
Note：背景
コードレビューや検証環境での結合試験を入念に行なってもバグが混入してしまう可能性はある。
→　リスクを0にすることは出来ない
:::

安全なデリバリーが行えると何が良いか?
　→　安心してデリバリー頻度を上げることが出来る
　≒　機能追加・改修のスピードを上げることが出来る

## 線形デプロイ / Canaryデプロイ
　安全なアプリケーションデリバリーを行うための代表的な手法として、線形デプロイとCanaryデプロイがあります。

　これらは図の通り、ALBなどを利用して、段階的に新バージョンのアプリケーションを公開していく手法です。現行バージョンへのトラフィックを減らしつつ、新バージョンへのトラフィックを増やしていくことで、新バージョンを利用するユーザーを増やしていき、最終的に完全に移行します。
 
　新バージョンで障害が発生した場合は、自動ロールバックを行い全てのトラフィックを現行バージョンへ戻します。（自動ロールバックについては本記事では紹介しないので、詳しく知りたい方はセッションを受講してみてください。）

![スクリーンショット 2024-09-11 7.34.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209951/b740829a-f4c1-5381-e394-73461aee5472.png)

### 線形デプロイ
　線形デプロイは名前の通り、予め設定した比率で少しづつ新バージョンへのトラフィックを増やしていきます。比率は10%ずつなどの数値をロードバランサーに設定可能で、慎重さをより重視する場合はこの線形デプロイが適していると言えます。

### Canaryデプロイ
　Canaryデプロイは少しずつではなく、一気に新バージョンへ切り替えます。初めに10%などの少数トラフィックに対してのみ新バージョンを公開し、問題がなければ段階を踏まずに100%に新バージョンを公開します。線形デプロイよりも簡易で、線形デプロイと比較して工数も少なく済みます。

![スクリーンショット 2024-09-11 7.43.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209951/f61bec62-18f9-749a-9261-8c09e8852535.png)

### 0→1プロダクトにはどちらが良いか？
　0→1プロダクトにはCanaryデプロイが適しているでしょう。一部のトラフィックで新バージョンの動作を確認しつつも、工程が少ないことでスピードも担保できます。まだユーザーが少ない0→1プロダクトや社内向けプロダクトなど、障害発生の影響の小さいものに適していると言えます。

　対する線形デプロイは慎重に動作確認を行いながらバージョンを切り替えていきます。そのため、既にある程度の数のアクティブユーザーがいる成熟したプロダクトや商用プロダクトなど、障害が発生した場合の影響が大きいものに適していると言えます。

## 機能フラグ
　機能フラグはアプリケーションコード内に、リクエストに対する新機能へのアクセスを制御する条件式を予め記述しておき、アクセス制御（機能フラグ）のON・OFFをクラウド側の設定で行うものです。

　線形/Canaryデプロイではトラフィックの割合を操作出来るだけだったのに対し、機能をフラグを使えばユーザーの属性を見て、特定のユーザーにのみ新機能を公開できます。例えばユーザーのIDやメールアドレスなどを用いて特定のユーザーのみに新機能へのアクセスを許可します。

　ただデメリットとしては、新機能へのアクセス制御の条件式をアプリケーションコードに記述する必要があり、コードの見通しが悪くなるだけでなく、後から条件式の削除を行う必要があるので保守性も下がってしまいます。

![スクリーンショット 2024-09-11 8.26.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209951/4b2a3d66-c5f6-2ed6-4396-f1aa8cb09bc1.png)

### 0→1プロダクトでの使い道
　0→1のプロダクトでは、一部ユーザーに対する新機能のフィジビリなどに利用することが出来るかもしれません。匿名ではない登録ユーザーが多いプロダクトの方が属性でユーザーを選別し易いため、特に社内向けプロダクトには向いていると思います。

　私が担当している営業向けプロダクトでも、例えば〜営業部１課にだけやインサイドセールス課の営業さんにだけなど、特定の属性にだけユーザーを絞ってフィジビリを行い、新機能の効果検証等を行うことが出来るでしょう。

## まとめ
　ここまで『AWS コンテナサービスから考える安全なアプリケーションデリバリー(AWS-34)』を受講して得た知識をもとに、それを私の担当する社内向け0→1プロダクトでどのように活用できるかを考えてきました。まとめとしては以下のようになります。

:::note info
「社内向け0→1プロダクト」の安全なデプロイ手法
Canaryデプロイが最適
→　トラフィック制御による段階的なデリバリーで安全性を担保しつつも少ない工程でスピーディーなデプロイ
:::

:::note info
「社内向け0→1プロダクト」の効果的な機能検証の手法
機能フラグが便利
→　ユーザーの属性を見て特定の人にだけ新機能を公開できるため、現プロダクトを動かしながら新機能のフィジビリなどを並行して行うことが出来る
:::

## 参考
　AWS Summit2024の[AWS コンテナサービスから考える安全なアプリケーションデリバリー(AWS-34)](https://www.youtube.com/watch?v=3Zin5h6lJXs)での受講内容を元に記事を作成しております。また記事内のスライドは全てこちらからの引用になります。
[Unity] WebGLビルドしたゲームをローカルサーバー(http)で動作させる設定のメモ

## 背景
WebGLでビルドしたものは原則としてhttpsに対応したサーバーでないと動作しない。

UnityがあればUnityが勝手にサーバーを立ててくれるので特段問題はないが
あまりITに強くない友人へファイルだけ渡して遊んでもらおうと思ったときに

ローカルにhttpsサーバーたてろというのはちょっと敷居が高い
(そもそもサーバーをたてろというのも酷ではあるが...)

というニッチな状況において以下の設定をすれば普通にhttpサーバーで動作したよというメモ


## ビルドセッティング

Edit > Player Setting > Player

Other Settings の `Allow downloads over HTTP*` という項目を`Always allowed`にする
Publishing Settings の `Compression Format`を`Disabled`にする

この設定でビルドするとhttpサーバー上で動作することを確認



ちなみにサーバーはNode.jsの`http-server`を使っている。
ビルドしたフォルダで`npm http-server .`とするだけで遊べる。
STATUS_ACCESS_VIOLATION



+ [Hello , When i am selecting a word in developer console and right clicking the page is showing an error in a new page "Aw, Snap!" something went wrong while displaying this webpage Error code: STATUS_ACCESS_VIOLATION. please can someone help me with it.?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007erRp9)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/bb86c962-ee2c-bac9-78c0-c7e87e38d9c5.png)


:::note
STATUS_ACCESS_VIOLATION の原因は何ですか?

古いブラウザ: ブラウザが古い場合、プログラム コードの不一致が発生する可能性があります。

ブラウザ拡張機能: 一部の拡張機能、特に広告ブロッカーがエラーの原因となります。

ブラウザ プロファイルが破損している: 拡張機能や設定の変更によりブラウザ プロファイルが破損している場合、エラーが発生する可能性があります。

破損したブラウザ ファイル: ブラウザに関連付けられたファイル (Chrome.exe など) が破損している場合、問題が発生する可能性があります。

不安定なブラウザ ビルド: Microsoft Edge と Google Chrome は、ベータ版、開発者版、および Canary チャネル用のビルドを提供しています。ただし、不安定になる可能性があります。

What Causes STATUS_ACCESS_VIOLATION?

Obsolete browser: If the browser is obsolete, it may lead to a mismatch of the program code.

Browser extensions: Some extensions, especially ad blockers, are responsible for the error.

Corrupt browser profile: If the browser profile is corrupt with extensions and changes in settings, the error may occur.

Corrupt browser files: If the files associated with the browser (eg. Chrome.exe) are corrupt, you may encounter the issue.

Unstable browser build: Microsoft Edge and Google Chrome offer builds for Beta, Developer, and Canary channels. However, they might be unstable.

https://mspoweruser.com/status-access-violation/
:::


+ [Can't login Playground App for Experience Cloud](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ifof1)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/74a6c2df-0c96-9762-06b8-e7cf01228563.png)

:::note
Try your browser's incognito mode.Or try it in a different browser.
:::
セキュリティトークン

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめN～Z](https://qiita.com/Keiji_otsubo/items/92f92bb9f668ca9688be)

---------------------

+ [Error: Check your username and password. If you still can't log in, contact your Salesforce admin.](https://qiita.com/Keiji_otsubo/items/0a3255e8031bd2e41764#error-check-your-username-and-password-if-you-still-cant-log-in-contact-your-salesforce-admin)
+ [API Only Users](https://qiita.com/Keiji_otsubo/items/be0f0696dac6a0d38bc7)
+ [[セキュリティトークンのリセット] オプションを表示できない](https://help.salesforce.com/s/articleView?id=000386179&type=1)

:::note
プロファイルに [ログイン IP アドレスの制限] セットが追加されている場合に、[私のセキュリティトークンのリセット] オプションが表示されない場合があります。  
:::


+ [アクセスからSalesforce内に入っているデータを抽出する方法](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007erPLB)

:::note alert
「セキュリティトークン」「追加の接続文字列パラメータ」が必要になります。
:::

:::note
+ ユーザー名、パスワード、トークンなど、必要な接続情報を特定します。 会社の信頼できる IP 範囲外のインターネット プロトコル (IP) アドレスから Salesforce にアクセスしようとすると、大文字と小文字を区別する英数字コードであるセキュリティ トークンを入力する必要があります。 詳細については、「 セキュリティ トークンをリセットする」を参照してください。
 

接続パラメーター

次の表は、[Microsoft Access - Salesforce に接続] ダイアログ ボックスの [追加の接続文字列パラメーター] ボックスに入力できる接続パラメーターを説明した一覧です。

複数のパラメーターがある場合はセミコロンで区切ります。 ガイドとして、次の構文例を参照してください。 

```
UID=myaccount;BulkBatchSize=9000;UseNumeric=1;
```
[Salesforce のデータのリンクまたはインポート](https://support.microsoft.com/ja-jp/topic/salesforce-%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E3%83%AA%E3%83%B3%E3%82%AF%E3%81%BE%E3%81%9F%E3%81%AF%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88-7375ffb6-1d6a-46f1-bb0c-c6ac3c58f5a0)

セキュリティトークンについてはもう一つ以下のような回避策もあります。セキュリティートークンが不要になると思います。

[設定] | [セキュリティ] | [ネットワークアクセス] で信頼できる IP 範囲を設定すると、これらの IP アドレスから認証を受けるユーザーは、ユーザーインターフェースのログイン時の本人確認や API 接続時のセキュリティトークンの必要性を回避することができます。ユーザーは、ログイン元の IP アドレスを認証するための 5 桁の確認コードを要求されることはありません。すべてのお客様向けアプリケーションとインテグレーションで、セキュリティトークンが不要になります。リストに記載されていない IP 範囲からログインしたユーザーは、確認コードまたはセキュリティトークンを提供することで認証を受けることができます。

https://help.salesforce.com/s/articleView?id=000386441&type=1
:::
Google Calendar APIで既存のMeetコードで会議を作成する方法

Google Calendar APIを使って、すでに作成済みのGoogle MeetのURLを使って会議予定を作成する方法を紹介します。

新規会議で予定を作成する方法は検索すれば多く出てきますが、既存のMeetコードを使って予定を作成する方法が日本語の記事では見つけられなかったので、メモとして残しておきます。

# 前提条件
認証などの基本的な使い方は以下を参考にしてください。

- [Google Calendar API JavaScript クイックスタート](https://developers.google.com/calendar/api/quickstart/js?hl=ja)
- [Events: insert | Google Calendar API | Google Developers](https://developers.google.com/calendar/api/v3/reference/events/insert?hl=ja#examples)

# 実装
## 手順1
新規イベントのオブジェクトに`conferenceData`フィールドを追加し、以下の内容を指定します。

``` javascript
// start, end, etc
'conferenceData': {
    'conferenceId': 'aaa-bbbb-ccc', // 既存のMeetコード
    'conferenceSolution': {
        'key': {
            'type': 'hangoutsMeet',
            'name': 'Meet Title' // 任意の名前
        }
    },
    'entryPoints': [
        {
            'entryPointType': 'video',
            'label': 'meet.google.com/aaa-bbbb-ccc', // 任意のラベル名
            'uri': 'https://meet.google.com/aaa-bbbb-ccc' // 既存のMeetコード
        }
    ],
},
```

## 手順2
さらに、APIを呼び出すときに、以下のクエリパラメータを追加します。
``` javascript
'conferenceDataVersion': 1
```

# 参考文献
- [Add a Google Meet to Calendar events with Google Apps Script - Oh hey, Brian](https://blog.ohheybrian.com/2020/05/add-a-google-meet-to-calendar-events-with-google-apps-script/)
nRFConnectSDKを基盤としたSesameの暗号通信 #13 AES-CMAC

![sesame](https://scontent-nrt1-1.xx.fbcdn.net/v/t39.30808-6/459031427_10221401363263806_5485314725821650337_n.jpg?_nc_cat=106&ccb=1-7&_nc_sid=127cfc&_nc_ohc=pJmROjH-TS8Q7kNvgE8w12L&_nc_ht=scontent-nrt1-1.xx&_nc_gid=AV-yy6ymKDvXzY9TTaXYxhW&oh=00_AYA_7ynTOxOguv8SOjELUZhKG5jwDa6ygf-WmCBzDluuuA&oe=66E6BEE6)

![cmac](https://scontent-nrt1-2.xx.fbcdn.net/v/t39.30808-6/459552462_10221412929712960_3116684680795004178_n.jpg?_nc_cat=102&ccb=1-7&_nc_sid=127cfc&_nc_ohc=V5xNaPCFPmEQ7kNvgEIuqEW&_nc_ht=scontent-nrt1-2.xx&_nc_gid=AJpXDK50bHqoaIVtONovYBC&oh=00_AYDU1ogpEkeqtktN9JKOpAydaiG_rzBSgd2daUxUm0sUKw&oe=66E8B256)

# 目的
最簡単なCMACの例


# code
``` c
#include "../cmake-build-debug/zephyr/include/generated/autoconf.h"
#include "../crypt/aes-cbc-cmac.h"

int main(void) {
    unsigned char key[16] = {
            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
    };
    unsigned char input[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                               0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
    };
    unsigned char mac[16];
    AES_CMAC(key, input, 16, mac);
    print_hex("CMAC", mac, BLOCK_SIZE);//2b79935c 27f4ce79 9c0779b4 fa521a58 

    return 0;
}

```
# 暗号化コード
- [aes-cbc-cmac.h](https://github.com/CANDY-HOUSE/SesameSDK_ESP32_with_DemoApp/tree/master/main/utils)

- [AES-CAMC online](https://artjomb.github.io/cryptojs-extension/)


# 雑談
AES-CMACのような暗号化コードを使用する際、異なるプラットフォームでの対応が異なるため、プラットフォームごとに再実装するのは非常に手間がかかります。そのため、ネットで見つけたAES-CMACのC言語ソースコードをそのまま使用する方法を取ることで、効率的に実装できます。ただし、これによりハードウェアアクセラレーションの可能性を犠牲にしている点には注意が必要です。
nRFConnectSDKを基盤としたSesameの暗号通信 #12 BLE-Mesh 用の暗号化技術(AES-CMAC ,AES-CCM,ECDH)

![sesame](https://telecom-engineer.blog/wp-content/uploads/2022/01/image-3.png)


# 目的
まず、暗号化に使用される3つの技術、ECDH、AES-CCM、AES-CMACについて、それぞれを簡単に紹介します。最も簡単なものから順に説明していきます。

### 1. **AES-CMAC (Cipher-based Message Authentication Code)**

**概要**:
AES-CMAC は、メッセージの認証に使用される技術です。これにより、データの整合性と真正性が保証されます。AES-128 (Advanced Encryption Standard) ブロック暗号を使用して、固定サイズの認証タグ（MAC）を生成します。

**用途**:
AES-CMACは、メッセージやデータの改ざんを検出するために使われます。たとえば、通信データが改ざんされていないことを確認するために利用されます。

**特徴**:
- データの整合性を確認するための認証コードを生成
- データの暗号化そのものではなく、データの改ざん防止に使われる

### 2. **AES-CCM (Counter with CBC-MAC)**

**概要**:
AES-CCM は、データの暗号化と認証を同時に行う暗号化モードの一つです。AES（Advanced Encryption Standard）を使用して、暗号化されたデータを生成し、さらに改ざんされていないかどうかも検証します。CCM は「Counter Mode」と「CBC-MAC（Cipher Block Chaining - Message Authentication Code）」の組み合わせです。

**用途**:
データの暗号化と、データが改ざんされていないことの確認を同時に行いたい場合に使われます。例えば、無線通信プロトコル（Bluetooth Low Energyなど）で、送信データを保護する際に使用されます。

**特徴**:
- データの暗号化（機密性の保持）と認証（整合性の確認）を同時に実行
- パケットのような限られたリソース環境で有効

### 3. **ECDH (Elliptic Curve Diffie-Hellman)**

**概要**:
ECDH は、楕円曲線ディフィー・ヘルマン（Elliptic Curve Diffie-Hellman）という暗号方式で、2者間で共有の秘密鍵を安全に生成するために使われます。お互いの公開鍵を交換し、その情報を基にして、共通の秘密鍵を計算します。この秘密鍵を使ってデータの暗号化を行うことができます。

**用途**:
ECDHは、セキュアな通信のための共有鍵を交換するために使用されます。BluetoothやWi-Fiの接続、またはエンドツーエンドの暗号化を必要とするアプリケーションで使われます。

**特徴**:
- 楕円曲線暗号に基づく安全な鍵交換方式
- 公開鍵を交換するだけで、秘密鍵を共有できる
- 大きな計算力を必要とせず、安全性が高い

### まとめ:
- **AES-CMAC** はデータの認証と改ざん検出に使用されます。
- **AES-CCM** はデータの暗号化と認証を同時に行い、特にリソース制限のある環境で有効です。
- **ECDH** は、安全な秘密鍵を生成するための鍵交換プロトコルです。

段階的に複雑さが増しますが、それぞれが異なる役割を持つ重要な暗号化技術です。



# 雑談
Sesame 用の暗号化技術は、実際には BLE-Mesh 用の暗号化技術と同じです。ただ、これはアプリケーション層で実装されているだけです。利点として、多くの細部を最適化でき、接続がより速く、Bluetoothペアリングが不要です。

# 用語
 
- [Aes]
- [AES-CMAC]
- [AES-CCM]
- [ECDH]
- [BLE-Mesh]
(構築2)snmpd(SNMPエージェント)の設定

# ■概略
オープンソースエンジニア歴30年超の筆者が2023年からIBMiを学びだした学習記録です
IBMiでsnmpd(snmpエージェント)を設定します

## <u>■参考URL</u>
https://tigertaizo.hatenablog.com/entry/2017/08/07/185204  
https://tigertaizo.hatenablog.com/entry/2017/08/09/222107  

## <u>■エージェント</u>
snmpエージェントは192.168.1.25/24
snmpクライアントは192.168.252.0/24

### ◯192.168.252.0/24からコミュニティ名COMM1でアクセスを許可する  
```
CHGSNMPA SYSD('AS400DEV2 SNMP AGENT') AUTOSTART(*YES) TRPMGR(('192.168.252.0' '255.255.255.0' 'COMM1' *YES))   

ADDCOMSNMP COM(COMM1) INTNETADR(('192.168.252.0' '255.255.255.0'))

STRTCPSVR SERVER(*SNMP)
TCP1A0F: SNMPサーバーは開始中である。
```

### ◯起動確認  
```
WRKACTJOB SBS(QSYSWRK)
QSNMPSA      QTCP        004386   QTCP        BCH    2  35        .0                  0     .0  PGM-QNMSARTR    DEQW          1          9
QTMSNMP      QTCP        004383   QTCP        BCH    2  35        .0                  0     .0  PGM-QTOSMAIN    DEQW          1          9
QTMSNMPINF   QTCP        004385   QTCP        BCH    2  50        .0                  0     .0  PGM-QTOSINF     DEQW          1          9
QTMSNMPRCV   QTCP        004384   QTCP        BCH    2  50        .0                  0     .0  PGM-QTOSRCVR    TIMW          1          8
```

## <u>■クライアント</u>
### ◯Linux(AmazonLinux2)(192.168.252.201/24)
```
[root@al2 ~]# yum install net-snmp-utils
```

### ◯全体取得
```
$ snmpwalk -v1 -c COMM1 192.168.1.25
```

### ◯CPU使用率
```
$ snmpwalk -v1 -c COMM1 192.168.1.25 1.3.6.1.4.1.2.6.4.5.1.0
```
SNMPv2-SMI::enterprises.2.6.4.5.1.0 = Gauge32: 20

### ◯DISK
＊hrStorage  
```
$ snmpwalk -v1 -c COMM1 192.168.1.25 1.3.6.1.2.1.25.2.3.1
```

＊DISK容量  
```
$ snmpwalk -v1 -c COMM1 192.168.1.25 HOST-RESOURCES-MIB::hrStorageSize.1
HOST-RESOURCES-MIB::hrStorageSize.1 = INTEGER: 607832064
```

＊DISK使用量  
```
$ snmpwalk -v1 -c COMM1 192.168.1.25 HOST-RESOURCES-MIB::hrStorageUsed.1
HOST-RESOURCES-MIB::hrStorageUsed.1 = INTEGER: 138680400
```
SSL/TLSについてざっくり理解してみる

# SSL/TLSとは

SSL/TLSとは、ホームページを格納しているサーバーとブラウザ間の通信を暗号化するための仕組み、プロトコルのことです。

TLSはSSLで重大な脆弱性が見つかり、バージョンアップされた結果、登場したSSLの次世代規格です。

現在使われているのは、ほとんどTLSのようですが、「SSL」や「SSL/TLS」という表現がされることが多いようです。

以降、本記事では「SSL」で統一しています。

# SSLで何ができるのか

SSLにより通信が暗号化されることで、悪意ある第三者からのデータの「**なりすまし**」「**改ざん**」「**盗聴**」を防ぐことができます。

次から、この3つのできることの仕組みをざっくり説明してみたいと思います。

# 「なりすまし」を防ぐ仕組み
![スクリーンショット 2024-09-11 083114.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831555/63b96d05-410b-dbe4-ddcd-a9d5628e5674.png)



1. クライアントからサーバーに対して、SSL接続のリクエストを送信します
2. サーバーは認証局に発行してもらったサーバー証明書と公開鍵※をクライアントに送信します
3. クライアントは送られてきた認証局の公開鍵を使用して、サーバー証明書を検証します
    
    ここでなりすましに気づくことができます
    
    ※ サーバー証明書と公開鍵を分けて記載していますが、実際はサーバー証明書の中に公開鍵が埋め込まれています、上の図で言うと免許証の女の子の写真が公開鍵になる感じです。
    

# 「改ざん」を防ぐ仕組み

![スクリーンショット 2024-09-11 084304.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831555/d516fcca-f78e-238b-ad57-e3d92f3ff97d.png)

1. クライアントは送信データ（HTTPメッセージ）とMAC値（送信データとMAC鍵 [※1] を混ぜてハッシュ化した値）をサーバーに送信
    1. この時これら2つのデータは共通鍵で暗号化されています。
    2. また、この共通鍵はサーバーから送られてきた公開鍵を用いて暗号化した上で、クライアントに送信されています。
2. サーバーは受信した送信データとサーバーのMAC鍵を使用して、MAC値を計算します
3. クライアントから送られてきたMAC値とサーバーで計算したMAC値を比較する
    
    ここで、MAC値が異なるのであれば改ざんに気づくことができます
    

※1 共通鍵を元に生成されたMAC値を生成及び検証するために使用される秘密の共有鍵

# 盗聴を防ぐ仕組み
![スクリーンショット 2024-09-11 084404.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831555/cea86c10-4b80-3011-54bd-b66df09e99ce.png)

上記のように盗聴を防ぐことができます。

「改ざんを防ぐ仕組み」のところで、HTTPメッセージとMAC値を共通鍵で暗号化しているところがありますが、その部分をより抽象化したのが上記の図となります。

# まとめ

ざっくりまとめてみましたが、ざっくりでも理解できていない部分が多く見つかりました。

また、より細かい仕組みについても以降まとめていきたいと思います。

本記事の内容に誤りがある場合はご指摘いただけると大変助かります。

# 参考文献

https://www.idcf.jp/rentalserver/aossl/basic/ssl-tls/

https://rs.sakura.ad.jp/column/rs/whats-ssl/?gad_source=1&gclid=Cj0KCQjw28W2BhC7ARIsAPerrcIJowWsplbs_M2asWnqYBuox1SWSrTEda9ApW5oxz0lxaUp2Sig0sAaAg2eEALw_wcB

 https://qiita.com/angel_p_57/items/446130934b425d90f89d
 
https://qiita.com/musakamama3838/items/937f6507bf70b3e032fd

https://www.gmo.jp/security/ciphersecurity/http-https/blog/https-protocol/

https://qiita.com/musenmai/items/43929eb9f6f31908fd51
windowsでiverilog その155

# 概要　
windowsでiverilogやってみた。
RP2040な、verilog見つけたので、テストベンチ書いてみた。

# 投入したpioasm

```
.program uart_rx
    wait 0 pin 0
    set x 7       [10]
again:
    in pins 1
    jmp x-- again [6]

```

# サンプルコード

```
`timescale 1ns/100ps
module test();
	localparam NONE = 0;
	localparam INSTR = 1;
	localparam PEND = 2;
	localparam PULL = 3;
	localparam PUSH = 4;
	localparam GRPS = 5;
	localparam EN = 6;
	localparam DIV = 7;
	localparam SIDES = 8;
	localparam IMM = 9;
	localparam SHIFT = 10;
	reg clk;
	reg reset;
	reg [31:0] din;
	reg [4:0] index;
	reg [3:0] action;
	reg [1:0] mindex;
	reg [31:0] gpio_in = 0;
	reg [15:0] program [0:31];
	wire [31:0] gpio_out;
	wire [31:0] gpio_dir;
	wire [31:0] dout;
	wire [3:0] tx_full;
	wire [3:0] rx_empty;
	wire [5:0] plen = 4;
	wire [23:0] div = 24'h0 ;
	wire [31:0] pin_grps = 32'h00000000;
	wire [31:0] exec_ctrl = 32'h00003000;
	integer i;
	task act (input [3:0] a, input [31:0] d);
		begin
			@(negedge clk);
			action = a;
			din = d;
			@(posedge clk);
		end
	endtask
	pio pio_1 (.clk(clk), .reset(reset), .action(action), .index(index), .mindex(mindex), .din(din), .dout(dout), .gpio_in(gpio_in), .gpio_out(gpio_out), .gpio_dir(gpio_dir), .tx_full(tx_full), .rx_empty(rx_empty));
	initial
		$readmemh("uart_rx.mem", program);
	initial
	begin
		clk = 1'b0;
	end
	always
	begin
		#20
			clk = !clk;
	end
	initial
	begin
		reset = 1'b1;
		repeat(2) @(posedge clk);
		reset = 1'b0;
		for (i = 0; i < plen; i++)
		begin
			index = i;
			act(INSTR, program[i]);
		end
		mindex = 0;
		act(PEND, exec_ctrl);
		act(DIV, div);
		act(GRPS, pin_grps);
		act(SHIFT, 32'h00810000);
		gpio_in[0] = 1;
		act(EN, 1);
		act(NONE, 0);
		repeat(2) @(posedge clk);
		gpio_in[0] = 0;
		for (i = 0; i < 10; i = i + 1)
		begin
			@(posedge clk);
		end
		gpio_in[0] = 1;
		repeat(80) @(posedge clk);
		gpio_in[0] = 0;
		repeat(20) @(posedge clk);
		act(PULL, 1);
		action = 0;
		repeat(20) @(posedge clk);
		$finish;
	end
	initial
	begin
		$dumpfile("test.vcd");
		$dumpvars(0, test);
		$display(" ac  din  out ");
		$monitor(" %h  %h  %h ", action, din, dout);
	end
endmodule





```

# 実行結果

```
>vvp a.out
WARNING: pio1.v:870: $readmemh(uart_rx.mem): Not enough words in the file for the requested range [0:31].
VCD info: dumpfile test.vcd opened for output.
 ac  din  out
 x  xxxxxxxx  xxxxxxxx
 1  00002020  xxxxxxxx
 1  0000ea27  xxxxxxxx
 1  00004001  xxxxxxxx
 1  00000642  xxxxxxxx
 2  00003000  xxxxxxxx
 7  00000000  xxxxxxxx
 5  00000000  xxxxxxxx
 a  00810000  xxxxxxxx
 6  00000001  xxxxxxxx
 0  00000000  xxxxxxxx
 0  00000000  01000000
 3  00000001  01000000
 0  00000001  000000ff
 0  00000001  01000000
pio1.v:911: $finish called at 57800 (100ps)

```

以上。
【SQL】Nullって意外とややこしい？

こんにちは、JSの勉強がひと段落ついたので現在SQLの勉強をしています。

その中でもNullってわかっていないと構文を覚えるのにも作業を進めていくにも大変と思ったので記事にしようと思いました。

# 1.Nullってそもそも何？
Nullというのは、データベース上でデータの中に値が存在しないことを指します。
下の画像でいうと黄色に着色されているところは値がありません。

![purchases テーブル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3883070/ec81d3dc-b1f5-2d2a-2573-de56d717ff63.png)

この場合は値がNullであるといいます。
ちなみに、Nullはラテン語由来らしく無って意味らしいです。
上記のデータはpurchasesテーブルとしておきます。

# 2.Nullを抽出したい場合
上記のpurchases テーブルからNullを含む行を抽出したい場合は以下のように出力します。

```sql:null.sql
SELECT * FROM purchases
WHERE price IS NULL;
```

以下のように出力されます
<br>
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3883070/2a7b1376-70ba-e444-28aa-91368d919e54.png)
<br>
では、理解を深めるためにpurchases テーブルpriceが300の行を主力してみましょう

```sql:null.sql
SELECT * FROM purchases
WHERE price =300 ;
```
<br>
下記のように出力することができました。

![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3883070/73daa756-85c7-92ab-97fc-047f8cf5f6a2.png)
<br>

ここで疑問に思うのが「300のような値を指定して主力することができるなら、price=Null;にしても出力できるのでは？」ということです。
値がないものをNullと定義しているなら＝にしてどうにか参照できそうですよね。

ここでもう一度Nullの定義に戻りましょう。
Nullとはセルの中に値がないものを指します。つまり値がないものを参照してもわからないということです。

例えば、google レンズなどの画像認識機能を使わずに以下の写真を見てください。

![S__18227202.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3883070/e4fd8cf5-1bde-3532-f2f2-49577e221fd6.jpeg)

「この写真に乗っている場所は埼玉県ですか？」Yes or Noで答えてと言われた場合困りますよね。左側に白州蒸留所のマークがあるのでわかる方にはわかりそうですが、、ｗ

コンピューター上ではほぼ同じことが起きています。

コンピューターは今回の場合のように写真などの情報も渡されず、WHERE price =NULL; つまり「値がないものを参照して」と言われてもないものを参照することができないのです。

つまりNullの場合は＝が使えないのでかわりに　IS NULL を利用するというわけですね。納得！

## Nullには等号だけでなく等号否定や不等号も使えない
上記のイメージがついた方なら大丈夫かと思いますが、等号同様不等号も使えません。

# 3.Null以外を抽出したい場合
Null以外を出力したい場合は以下のコードを使用します。
<br>

```sql:null.sql
SELECT * FROM purchases
WHERE price IS NOT NULL;
```
以下のように出力できます
![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3883070/04dac598-5f44-927a-6a66-89c4727b1176.png)


上記のNullの説明でしましたが＝が使えなので代わりにIS NOT NULLを使用しています。

# 4.Nullと空文字の違いについて
結論から伝えるとNullと空文字は別物です。
例えば、今ここに真空の容器と空気が入っている普通の容器があったとします。

真空の容器は言うまでもありませんが空気をすべて抜いているので中には何も入っていません。

一方で空気の入っている普通の容器は、中に空気（窒素約80％、酸素約18％）が入っているので一見からですが中には空気が入っています。

![画像5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3883070/ebe8d10e-5ebe-0603-c9fd-f7dd03c70e4e.png)

つまり、Nullは値が何もないのに対し、空文字は長さ0の文字列、すなわち、空のデータが存在すると表現することができます。

もっと踏み込むとNullは数字列の空白、空文字は文字列の空白です。

以下のpurchases1で試しに空文字を出力してみましょう。

![文字列.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3883070/a7de6183-fa2c-1888-1b2b-bab4656afdf3.png)
<br>

```sql:null.sql
SELECT name
From purchases 
WHERE name ='';
```

出力結果は0となります。意外かもしれませんが上記の通り空文字には長さ0の文字列が入っているということになります

# まとめ
今回はNullについての考え方についてまとめました。正確な概念は若干間違っているかもしれませんがイメージについてはあっているかと思います。

重大なミスがあれば指摘していただけるとありがたいです。
どんどん積極的にアップデートしていきたいと思います。
paizaラーニング問題集「二次元累積和」を解いてみた

▼感想：

累積和の計算方法のやりかたを踏まえて、本問を解くことができました。

▼コード：

    ########## 処理0(準備) インプット,リスト定義など ###########

    H,W,N = map(int,input().split())

    A = [[0 for i in range(W)] for j in range(H)]

    # ruisekiwa_yoko,ruisekiwa_tate: 横方向,縦方向の累積和格納用リスト
    ruisekiwa_yoko = [[0 for i in range(W)] for j in range(H)]
    ruisekiwa_tate = [[0 for i in range(W)] for j in range(H)]

    ########## 処理1 横方向の累積和の計算、格納 ##########
    
    for j in range(H):
    
        A[j] = list(map(int,input().split()))
    
        ruisekiwa_yoko[j][0] = A[j][0]
    
        for i in range(W-1):
             ruisekiwa_yoko[j][i+1] = ruisekiwa_yoko[j][i] + A[j][i+1]

    ########## 処理2 縦方向の累積和の計算、格納 ##########
    
    for i in range(W):
    
        ruisekiwa_tate[0][i] = A[0][i]
    
        for j in range(H-1):
             ruisekiwa_tate[j+1][i] = ruisekiwa_tate[j][i] + A[j+1][i]

    ########## 処理3 入力に応じた累積和の計算 ##########
    
    for _ in range(N):

        # total: 計算した累積和の格納用変数
        total = 0    
        y,x = map(int,input().split())
    
        # 入力が横長
        if y < x:
            for j in range(y):
                total += ruisekiwa_yoko[j][x-1]
    
        # 入力が縦長、または横と縦が同じ長さ
        else:
            for i in range(x):
                total += ruisekiwa_tate[y-1][i]
    
        print(total)
部屋の構造を変えずにインテリアデザインができるAIアプリを個人開発しました

こんにちは！

インテリアデザインのパースって、いちから作るのかなり大変じゃないですか？

スケッチだったり3Dモデルだったり、クオリティ確保しつつすぐに完成なんてなかなか難しいですよね。そんな方にオススメしたいアプリがあります🎉

インテリアデザインAIアプリ**「もようがえAI」**

# 🤔もようがえAIって？

建築の内観パースをAIと一緒につくるアプリです。

建築学生の私が設計課題のときに、「内観パースをさくっと作ってもっとイメージを膨らませたい」と思ったことがきっかけで作ったアプリです

# 🏠️つくった理由は？

試しの内観パースをぱぱっと作れるようにしたかったからです。

このときはいつも模型や図面に追われてしまい、内観の検討が全然できずにいました🤯

そんなときに生成AIでパースを作成できる記事を見つけ、これを活用できないかと考え始めました。

ただほかのサービスでよくあるのは、"テキストを入力すると画像が生成される"というものばかりだったので、あまり思い通りのパース図作成ができませんでした。

そこで思い通りのパース図を作成するために、家具の任意位置の固定が可能な「もようがえAI」をつくりました。

# 💫特徴

①家具の位置が固定できる

アプリ内で元画像の好きな位置に家具モデルの配置ができます。

AIがきれいにレンダリングできるように、椅子や机の家具サンプルデータを用意しています。
![1000002933.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647151/389bdaa5-3524-ea64-0a3e-f0b41e2357b8.png)

②部屋の構造が変わらない

インプットした画像から構造を読み取っているため、画像生成AIでよくある全く別の部屋にならないようになっています。
![1000002934.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647151/4108562d-52f9-2184-fc4d-988f14b9d2e6.png)


③操作が簡単

画像のインプットと家具追加が終わったら、・部屋のタイプ・部屋のテーマ・色のテーマを選択するだけで完了です。

30秒ほど待つと、4枚の画像が生成されます。
![1000002937.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647151/861a2a47-a7f1-abdb-24e6-c233e0fb3b38.png)


# デモ
https://youtube.com/shorts/y-5IwWkVEz8?si=_EytwdTLEoYPtH6-

# おわりに

いつも時間が足りない建築学生や建設会社勤務の方に、すこしでもお役立てていただけると幸いです。

読んでいただきありがとうございました。
【AWS】VPC でサブネットを作成する

# はじめに
この記事では、AWS VPC でサブネットを作成する手順を記載します。

https://aws.amazon.com/vpc/

:::note
以後の画面キャプチャは 2024年8月時点のものです。
:::

# サブネット作成画面へアクセスする
VPC ダッシュボードで「Subnets」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/5cba9aec-2167-45d8-3ba2-2feb1532515d.png)

サブネット一覧画面が表示されます。この画面で「Create subnet」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/b5097c2e-accf-6a2d-f86f-e46eaff5841c.png)

# サブネットを作成する
サブネット作成画面には、以下2つのセクションがあります。

- VPC
- Subnet settings

セクションごとに設定を進めています。

## VPC
サブネットが所属する VPC の ID を選択します。

※VPC の作成手順については、以下の記事に記載があります。

https://qiita.com/Yasushi-Mo/items/d5845d312fedce37e1d6

## Subnet settings
Subnet settings では、以下の値を設定します。

- Subnet name : web-subnet-01
- Availability Zone : Asia Pacific (Tokyo) / ap-northeast-1a
- IPv4 CIDR block : 10.0.0.0/21
- IPv4 subnet CIDR block : 10.0.0.0/24

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/f9098ea3-8903-7e2b-262e-3ad43acb1a52.png)


:::note warn
Availability Zone で「Asia Pacific (Tokyo) / ap-northeast-1a」を選択するためには、IAM ユーザーのリージョンが「Tokyo」である必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/5c86d1e6-b6de-59df-aa0d-20d751337764.png)

:::

全て入力したら「Create VPC」をクリックします。

画面上部に作成成功メッセージが表示されていれば、成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/5dc80384-bb6b-1ba9-6791-e5e71018ff68.png)


# 参考
- [Amazon Virtual Private Cloud Documentation](https://docs.aws.amazon.com/vpc/)
- [What is Amazon VPC?](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html)
- [小山雄太「WebアプリをAWSで公開しよう【AWSハンズオン虎の巻シリーズ】: 初心者も安心！手を動かしながらAWSの基本がしっかり学べる一冊！」2023](https://www.amazon.co.jp/Web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92AWS%E3%81%A7%E5%85%AC%E9%96%8B%E3%81%97%E3%82%88%E3%81%86%E3%80%90AWS%E3%83%8F%E3%83%B3%E3%82%BA%E3%82%AA%E3%83%B3%E8%99%8E%E3%81%AE%E5%B7%BB%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%E3%80%91-%E5%88%9D%E5%BF%83%E8%80%85%E3%82%82%E5%AE%89%E5%BF%83%EF%BC%81%E6%89%8B%E3%82%92%E5%8B%95%E3%81%8B%E3%81%97%E3%81%AA%E3%81%8C%E3%82%89AWS%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%8C%E3%81%97%E3%81%A3%E3%81%8B%E3%82%8A%E5%AD%A6%E3%81%B9%E3%82%8B%E4%B8%80%E5%86%8A%EF%BC%81-%E5%B0%8F%E5%B1%B1-%E9%9B%84%E5%A4%AA-ebook/dp/B0CH7P3SQM)
末尾再帰最適化

# はじめに
「フィボナッチ数列」を題材に末尾再帰最適化の効果を解説します。


# 前提知識
末尾再帰最適化の効果を評価する指標として、計算量とオーダー記法を用います。コンピュータ科学の世界では、アルゴリズムの効率を評価するために「計算量」という概念が頻繁に使用されます。

### 計算量とは
計算量は、ある処理を行うために必要なリソースの量を示す指標で、時間計算量と空間計算量の2つの主要な種類があります。時間計算量は、アルゴリズムが問題を解決するために必要な計算ステップの数を示します。一方、空間計算量は、アルゴリズムが問題を解決するために必要なメモリの量を示します。計算量を表現するために広く使用される記法が「オーダー記法」です。

### オーダー記法とは
計算量を表現するために広く使用される記法が「オーダー記法」です。オーダー記法は、アルゴリズムの計算量を表現するための記号で、データ量がnであったとき、どれくらいの計算が必要になるかを示します。


# 本題

### フィボナッチ数列の漸化式

```math
F_0 = 0
<br>
F_1 = 1
<br>
F_n+2 = F_n + F_n+1 (n ≧ 0)
```
Github Actions の CI で必須の WorkFlow を設定する 

# 設定方法

Workflowのファイルには直接指定できないので、Github上から設定する必要がある

レポジトリの Settings から設定できる

![CleanShot 2024-09-11 at 07 30 43@2x](https://github.com/user-attachments/assets/8ffb3848-e347-4575-b8f6-047ca8928de0)

ブランチ単位でWorkflowの種類を選べばOK

![CleanShot 2024-09-11 at 07 31 00@2x](https://github.com/user-attachments/assets/da078ef2-92f1-4060-94b1-04f348319aa1)



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
スライドショーを作る

# スライドショーを作る

## powerpointあれば

powerpointがあれば、その機能をつかって実現可能なのですが、ここではそれをつかわずに実現する方法を考えます。

## 音声の部分

音声は読み上げです。いわゆるTTSです。
voicevoxなどのTTSアプリで発生させます。

## スライドショーの部分

Xの部分にはトータル上映時間をいれてください

```
ffmpeg -f concat -safe 0 -i image.txt -t X tmp.mp4
```

image.txtは次のような感じでつくりました。

```
file 'image1.jpg'
duration 5
file 'image2.jpg'
duration 3
file 'image3.jpg'
duration 7
```

## 音声と画像をあわせます

```
ffmpeg -i tmp.mp4 -i output1.mp3 -c:v copy -c:a aac -strict experimental SS1.mp4
```
Testlimit でリソース負荷テスト🔥

## Testlimit とは？
Testlimit は、Windows Sysinternals の一部で、システム リソースの負荷テストするためのツールです。このツールを使うと、プロセスでメモリ、ハンドル、スレッドなどのリソースを意図的に消費し、システムの限界や動作を確認できます。Testlimit はシステムのパフォーマンスや安定性のテスト、リソース管理の問題を検証する際に役立ちます。また、どのリソースがシステムのパフォーマンスに最も影響を与えるかを把握することができます。

Testlimit - Sysinternals
https://learn.microsoft.com/en-us/sysinternals/downloads/testlimit

あまり頻繁に使うわけではないけど、使う時なんだっけ？状態になるので、書いておきます。

## 仮想メモリ
```powershell
# 1024MB の仮想メモリを1秒ごとに5回確保（つまり 5GB）
Testlimit64.exe -m 1024 -e 1 -c 5
```
プロセスが使用している仮想メモリのサイズは、タスクマネージャーでは、**コミット サイズ** の項目で確認できます。

![commit_size.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853334/2a4dfbd4-7a5b-d174-e063-9c06a9a955df.png)

## 物理メモリ
```powershell
# 1024MB の物理メモリを1秒ごとに5回確保（つまり 5GB）
Testlimit64.exe -d 1024 -e 1 -c 5
```
プロセスが使用している物理メモリのサイズは、**ワーキングセット（メモリ）** の項目で確認できます。もちろん仮想メモリのサイズも大きくなります。

![workingset.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853334/29984d2f-c5b3-6331-d0d3-89d48b15ee6c.png)

仮想メモリと物理メモリの関係について知りたいという人は、タスク マネージャーの見方で説明したので、こちらを読んでいただければと思います。

タスク マネージャーの見方（Memory） | Microsoft Japan Windows Technology Support Blog
https://jpwinsup.github.io/blog/2021/05/10/Performance/SystemResource/TaskManagerMemory/

## ハンドル
```powershell
# ハンドルを 10,000 個確保
Testlimit64.exe -h -c 10000
```
プロセスが保持しているハンドルの数は、**ハンドル数** の項目で確認できます。

![handle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853334/3c8dc408-63d1-17d5-89ef-ead572bb1933.png)

ハンドルについては、Microsoft の Web サイトで紹介されています。

ハンドルとオブジェクト - Win32 apps | Microsoft Learn
https://learn.microsoft.com/ja-jp/windows/win32/sysinfo/handles-and-objects

## スレッド
```powershell
# スレッドを 1000 個生成
Testlimit.exe -t -c 1000
```
プロセスが実行しているスレッドの数は、**スレッド数** の項目で確認できます。

![thread.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853334/29a06bd8-f0ae-1b14-758b-b8cf822673a0.png)

## さいごに
他にも、いろいろできますが、マニアックなリソースになるので、気になる人はオプション全部ためしてみてくださいね。
再帰関数のイメージがつきづらい！

## はじめに
再帰関数の処理を見ているとなんでそうなる？！と理解に時間がかかったので知識の定着のために記事書いていきます

## 再帰関数とは
再帰関数とは、呼び出し元関数への復帰場所を記憶します。これは、問題を解決するために、自分の処理を繰り返し行うことを意味します。

**<再帰関数の基本的な考え方>**
再帰関数を使うときは、次の2つの要素が必要です：

1.再帰呼び出し
関数の中で、自分自身を呼び出します。
これにより、問題を小さな部分に分けて処理することができます。

2.終了条件
再帰呼び出しを終了するための条件を設定します。
終了条件がないと、関数が無限に呼び出され続けてしまいます。

## 再帰関数の例
```java: 再帰関数
void count(int n) {
    if (n > 0) {
        count(n - 1); // 自分自身を呼び出す
        printf("%d\n", n); // 数字を表示する
    }
}
```

```java:関数呼び出し
count(3)
```

**～ながれ～**
```
1. count(3) の呼び出し
スタックに count(3) の状態が保存されます。
count(2) を呼び出します。

2.count(2) の呼び出し
スタックに count(2) の状態が保存されます。
count(1) を呼び出します。

3. count(1) の呼び出し
スタックに count(1) の状態が保存されます。
count(0) を呼び出します。

4.count(0) の呼び出し
スタックに count(0) の状態が保存されます。
count(0) の処理が終了し、スタックから count(0) の状態が取り出されます（つまり、count(0) が終了します）。
スタックから戻る

5.count(1) に戻る
count(0) が終了すると、スタックから count(0) の情報が取り出され、count(1) の実行が再開されます。
printf("%d\n", 1); が実行されます。
count(1) が終了すると、スタックから count(1) の情報が取り出され、count(2) の実行が再開されます。

6.count(2) に戻る
count(1) が終了すると、スタックから count(1) の情報が取り出され、count(2) の実行が再開されます。
printf("%d\n", 2); が実行されます。
count(2) が終了すると、スタックから count(2) の情報が取り出され、count(3) の実行が再開されます。

7.count(3) に戻る
count(2) が終了すると、スタックから count(2) の情報が取り出され、count(3) の実行が再開されます。
printf("%d\n", 3); が実行されます。
count(3) が終了し、全ての処理が完了します。
```

## どういう仕組み？
まずこの解説をみたときに、戻るということはメモリをたどっていってるみたいな感じなのか？と思ったのですが正解でした。
スタックメモリが使用されているようです。

＜再帰呼び出しの仕組み＞
関数呼び出しでは、呼び出し元の「変数の値」と「実行位置」をスタックに保存します。これにより、どこまで処理が進んだかを記録できます。
再帰呼び出しでも、現在の状態をスタックに保存して再び自分自身の関数を呼び出すので、再帰呼び出し処理から戻ってきたときに正しく処理を続けることができます。

＜スタックという仕組み＞
プログラムが関数を呼び出すと、スタックという記憶場所に呼び出し元の状態（変数の値や実行位置）を保存し、その上に呼び出された関数で使用するローカル変数領域を確保します。
関数を呼び出すたびにスタックに情報が積み上がり、関数の処理が終わると最後に保存した呼び出し元の状態を復元します。

＜スタックの役割＞
スタックは、関数が呼び出されたときの状態（変数の値や実行位置など）を保存し、関数が終了するまでその状態を保持します。これにより、再帰呼び出しが終了した後に元の関数の処理を再開できるのです。

## まとめ
とにかく難しいですが、細かくくだいていくと理解できました。実際に再帰関数を使用してコードを書く機会は少なさそうですが概念だけでもイメージできてよかったです