OmniAICreator/Qiita-1.07M huggingface dataset:
Reactでハンバーガーメニューの実装（外部ライブラリ無し）

どうもこんにちは、たくびー(@takubii)です。

今回はReactでハンバーガーメニューの実装を行ったので備忘録として記事にしたいと思います。
昨今だとライブラリなどであるかもしれませんが、今回はライブラリを使わずReactの機能とWeb標準のみで実装しています。

## 簡単に説明

ロジックが多いですが、少し凝ったことをしていて、アニメーションが始まった時にサイドバーが出現し、終わった時に消えるようにしています。
サイドバー展開中はコンテンツにオーバーレイを被せることでコンテンツへのクリックを制限しています。
また、オーバーレイ自体に触るとサイドバーが消えるようになっているので少しユーザーフレンドリーかなと思います。

## 実装

:::note info
アイコンはBootstrap Iconを使用しています。
:::

```jsx:jsx
export const App = () => {
  const [menuOpen, setMenuOpen] = useState(false);
  const toggleMenu = () => {
    const sidebar = document.querySelector('.sidebar');
    if (!menuOpen) {
      sidebar.style.display = 'block';
      setTimeout(() => {
        setMenuOpen(true);
      }, 10);
    } else {
      setMenuOpen(false);
    }
  }
  const closeMenu = () => {
    setMenuOpen(false);
  }

  useEffect(() => {
    const sidebar = document.querySelector('.sidebar');
    const handleTransitionEnd = () => {
      if (!menuOpen) {
        sidebar.style.display = 'none';
      }
    };
    sidebar.addEventListener('transitionend', handleTransitionEnd);

    return () => {
      sidebar.removeEventListener('transitionend', handleTransitionEnd);
    };
  }, [menuOpen]);

  <div className='header'>
    <div className='hamburger-menu' onClick={toggleMenu}>
      <i className='bi bi-list'></i>
    </div>
  </div>

  {menuOpen && <div className='overlay' onClick={closeMenu}></div>}

  <div className={`sidebar ${menuOpen ? 'open' : ''}`} style={{ display: 'none' }}>
    <div className='hamburger-menu-close' onClick={toggleMenu}>
      <i className='bi bi-x-lg'></i>
    </div>
    <p>test1</p>
    <p>test2</p>
    <p>test3</p>
  </div>

  <div className='contents'>
  </div>
}
```

```css:css
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  z-index: 999;
}

.sidebar {
  position: fixed;
  top: 0;
  width: 250px;
  height: 100%;
  background: white;
  transform: translateX(-100%);
  transition: transform 0.3s ease-in-out;
  z-index: 1000;
}

.sidebar.open {
  transform: translateX(0);
}

.sidebar .hamburger-menu-close {
  display: inline-block;
}
```

## 終わりに

横から出てくるタイプのハンバーガーメニューはいろいろな場所で目にしますが、実際に実装してみると結構手間がかかるなと思いました。
車輪の再発明になっているかもしれませんが、もし実装で困っている方の助けになれば幸いです。

それでは今回はこのあたりで締めたいと思います。
ここまで読んでいただきありがとうございます。
また機会があればお会いしましょう。
EC2インスタンスにセカンダリプライベートIPが紐づかなかった話

1. 事象：EC2インスタンス（m7i.large）にセカンダリIPアドレスを紐付け用とした際にAWSコンソール上ではアタッチされているがOS側（RedHat9）からは認識しないという問題が発生した。

2. 原因：ネットワークマネージャーのバージョンが古いこと
→最近のOSではAWS側で複数のIP、ENIをアタッチした時にOS側でも自動で認識して設定を変更してくれるようになっているのだが、RedHat9環境のこのインスタンスではネットワークマネージャーのバージョン差異が発生し、この自動設定が行われなかった。

3. 解決：ネットワークマネージャーのバージョンを上げたら解決

参考記事：
https://dev.classmethod.jp/articles/rhel-nm-cloud-setup/
Bootstrapの動作不良

## 概要
Boostrapを導入し問題なく開発していたが、いざデプロイした時にレスポンシブ表示が実現できず。原因を調べているうちに開発環境でも動作しなくなりハマってしまったので記録しておきます。

## 結論
aplication.html（haml）にBootstrapを読み込むためのスタイルシートを書けば動作するようになる。
また、開発環境ではプリコンパイルして作成されたアセットを削除すると動作するようになる。
スタイルシートについては[公式ドキュメント](https://getbootstrap.jp/docs/4.5/getting-started/introduction/)に思いっきり書いてあるのに見落としていた。

## 経緯
開発環境でレスポンシブ表示のためにBootstrapを導入。問題なく動作していたが、いざデプロイしてアプリを開いてみるとレスポンシブ表示されていない。JavaScriptなどは効いているようだったのでBootstrap周りに問題があると推測。


本番環境で動作しない原因を調べるために、開発環境でプリコンパイルを実行し本番環境に切り替えて状況を合わせてみることにした。
その後、開発環境でもBootstrapが効かなくなる。

調べたところ、開発環境で効かなくなった原因はプリコンパイルだった。
プリコンパイル時にアセット（CSSやJavaScriptファイルが圧縮されたもの）が作成されており、アセットがある場合は通常のCSSファイルなどより優先的に読み込まれてしまう。

開発環境の方は一度アセットをpublicディレクトリ丸ごと削除し通常のCSSファイルが読み込まれるようになり解決。同時に、アセットを調べる中でBootstrapのアセットも正常に生成されており、問題なく読み込まれるはずと確認できた。

読み込みに問題があると推測し、あらためて[公式](https://getbootstrap.jp/docs/4.5/getting-started/introduction/)のセットアップ方法を確認。
ここで原因がはっきりした。

下記の読み込みテンプレートを入れていなかった。

１つ目はhead内側に他のスタイルシートよりも先に入れる。

```
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
```
 そして下記のコードをbodyタグ終了の直前に順番通りにいれる。
```
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
```

本番環境の方は公式に出ているスタイルシートの読み込み（pack_tag）をapplication.html（実際はhaml）に書いていなかったことが原因だった。開発環境ではpack_tagを書かずになぜか動作していたので記述漏れに気がつかなかったが、記述し直してデプロイしたら本番環境でもレスポンシブが効くようになった。
How Incredible!! A breakthrough New Application with YDLIDAR!

日本のMktechlabはYDLIDAR T-Mini Proを搭載したハンドヘルドSLAMスキャナーを開発しています：
ハンディプロジェクターにすることもできます！
-------------------------------------------------------------

Mktechlab from Japan is developing a handheld SLAM scanner with the YDLIDAR T-Mini Pro, which is performing great! :robot:
You can even made it a handy projector!


![case.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491551/c8c5209b-6611-77d8-d10c-6ea8373d8798.jpeg)
![GEDLH97WUAE2wyK.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491551/5abf9253-d7f9-583c-d93b-8af153b13341.jpeg)
【UiPath】Insightsを使ってジョブ・キュー・マシンをリアルタイムに監視する

# はじめに
:::note warn
注意：本記事はプレビュー機能を含みます。
:::

エンタープライズでRPAを使用する場合、監視がより重要になります。
UiPathの場合、ジョブなどのステータスを監視する方法としては、ワークフローに通知機能を実装したり、Webhookを使用する方がありました。

https://qiita.com/shuy/items/febcfd1677d17eda17fc

今回は、Automation Cloud上で完結する監視方法を考えてみます。


# つかうもの
※クラウド環境は2024年3月時点のもの
Automation Cloud(Insights, Orchestrator) Enterprise版


# リアルタイム監視ダッシュボード
2024年2月、Insightsではリアルタイム監視機能がプレビューとしてリリースされました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/fa63d860-e567-4d12-f556-11d40beccb56.png)

このダッシュボードを使うことでプロセス（ジョブ）、キュー、マシンのリアルタイムの状態を可視化できます。
通常、Orchestrator-Insights間のデータ連携は15～30分くらいのラグが発生するため、厳密なリアルタイムの監視には適していませんが、リアルタイム監視機能では1分程度のラグになっています。


## ジョブのリアルタイム監視ダッシュボード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/854ee07a-8542-4d44-d2f1-e4bd42786ba9.png)

ダッシュボード画面は１分おきに自動で更新される仕様のようです。なので監視チームは常時画面を開きっぱなしにすることもできます。

ダッシュボードには以下のウィジェットが含まれます。
* ジョブの成功率
* 完了（成功または失敗）ジョブ数
* 未完了（実行中や中断など）ジョブ数
* 失敗したプロセス
* エラーの詳細
* プロセス別の実行状況（成功数、失敗数、平均実行時間など）

ダッシュボードに表示する期間は、直近の１分間から24時間まで選択できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/017769e1-76ef-8d19-a495-fa09c9a8fd98.png)


# リアルタイム監視アラート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/d48a8ede-5a11-95ae-acf1-211608c9cf68.png)

リアルタイム監視機能のアラートはトリガー条件を満たす度、Automation Cloudに登録したアカウント（メールアドレス）に通知する機能です。

例えば、ジョブがエラーになると以下のようなメールを受信できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/e89509c5-cac2-4f69-04f1-2fc7386e4f7d.png)


## ジョブのリアルタイム監視アラート
ジョブのアラートは以下の条件で発報できます。

**特定ステータスのジョブ数**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/4ef554b6-6c52-ec0a-7b91-fdb8b5ef0dfe.png)

ジョブが失敗した際の通知などに使用します。「Status:Faulted >= 1」のように設定すると、ジョブが失敗する度にメールが送信されます。

**未完了ジョブの実行時間**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/7dac22c8-cbc7-fbe7-5720-70b9b20c2645.png)

保留中のまま放置されたジョブがあるなどの通知に使用します。「Status:Pending >= 10」のように設定すると、ジョブが10分以上保留のままになるとメールが送信されます。

**完了ジョブの実行時間**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/f093095e-45e3-f40d-217d-0ad8be320351.png)

何かしらの問題により実行時間が長くなっているジョブを発見する場合に使用します。1回の実行時間または、平均実行時間のどちらか選択します。

アラート対象のジョブを集計する期間を選択できます。厳密にリアルタイムの状況を把握したい場合は、期間はより短く設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/24e6e93d-a302-bcac-4889-a22a8eeea728.png)


# おわりに
元々、Insightsはデータ連携のタイムラグがあるためリアルタイム監視に適さず、稼働状況の分析・棚卸目的で使用されること多かったのですが、リアルタイム監視機能がリリースされたことで、ライセンス費用に対するROIが向上したと思います。

通知に関しては、もう少し機能が充実しても良いかと思いました。例えば、Exceptionクラスの種類でフィルタリングできるとか。SystemExeptionは運用・監視チーム、その他Exceptionは業務チームに通知先を振り分けるなどできたらいいなと思いました。

とはいえ、良い機能アップデートなので是非、プレビューからGAへ昇格してほしいです。
ぼくがつくったさいきょうのおーえすを語ろう#2(解説編)

# このシリーズについて
このシリーズは私がSecHack365(2023年度学習駆動コースの坂井ゼミです)を通して制作した「ぼくがつくったさいきょうのおーえす(Shizuku)」についてただただ語るだけのシリーズです。もし興味があればGitHubを覗いてくれると嬉しいです。[Open Source Conference 2024 Tokyo/Spring](https://event.ospn.jp/osc2024-spring/)にも出展するのでもし興味がありましたら来ていただけると嬉しいです。
# 構成
---↓#1はここから---
1. ぼくがつくったきっかけ
2. さいきょうとは何か
3. OSとは何か
---↑#1はここまで---
---↓この記事はここから
4. つくったおーえす
5. オブジェクトとオブジェクトシステム
---↑この記事はここまで---
# つくったおーえす
実はまだAPIドキュメントすらないOSなので恐縮ですが僕はオブジェクトシステムという概念(他のOSでいうところのVirtual File Systemに相当するもの)を搭載した[Shizuku](https://github.com/danfunc/Shizuku.git)というOS(というかほぼカーネル)を作りました。[#1](https://qiita.com/DanfuncL/items/ebdfdaffa1b852ab19b9)で紹介したOSの役割をもう一度整理すると
- デバイス操作
- デバイスの抽象化
- プログラム(プロセス)間通信
- リソース管理

をOSは実現するべきということが言えます。OSにはカーネルと標準アプリケーションの2つの部分に大別され、Linuxカーネルに標準アプリをインストールしたものがDebianやArchといったLinuxディストリビューションを作ります。そして↑のリストはLinuxでは基本的にカーネルが担当しています。Shizukuではプログラム間通信と処理能力(CPU時間)と記憶能力(メモリ領域)の管理(プログラムへの割り当て)のみカーネルが担当し、デバイス操作やデバイスの抽象化は標準アプリ(に位置付けることができるもの)によって行われます。設計としてはマイクロカーネル(GNU Hurd)やハイブリットカーネル(XNU)と呼ばれるものに近いですが、オブジェクトシステムによってデバイス抽象化が行われることと、全てのプログラム間通信はオブジェクトシステムを利用して行われるというところが大きな違いとなっています。
# オブジェクトとは
Shizukuではオブジェクトを、
- 処理能力(管理単位はthread)と記憶能力(管理単位はメモリマップ)を持った存在(第一定義)
- オブジェクトは別のオブジェクトから呼び出せるメソッドを保有している(第二定義)
- オブジェクトは他のオブジェクトのエイリアス(ファイルディスクリプタのようなもの)を持つことができ、そのエイリアスはO(1)(最速)で呼び出せる。(エイリアス化されていないメソッドを呼び出す時はエイリアス化されてるメソッドよりも呼び出しが遅くなるかもしれない)(第三定義)
- オブジェクトは配下(手下、子)オブジェクトを持てる。親オブジェクトが終了する(消える)と子オブジェクトも終了する(消える)(第四定義)
- オブジェクトには特権オブジェクトと一般オブジェクトの二種類が存在して、一般オブジェクトは配下の一般オブジェクトのみ自由にでき、特権オブジェクトは他のすべてのオブジェクトを自由にできる(第五定義)
と定義しています。と言っても最初から第五定義まで決まっていたわけではなく、上から下へと機能が足りなくなるたびに必要な定義の拡張を行いました。(ちなみに第五定義に関してはまだ明確に定まり切れてません。)
# オブジェクトシステムの機能
Shizukuのメイン機能であるオブジェクトシステムは次のような機能を一般・特権両方のオブジェクトに提供します。
- 処理能力の取得(スレッドの作成)
- 記憶能力の取得(メモリマップの作成)
- 配下オブジェクト・親オブジェクトのメソッド呼び出し(特権オブジェクトのメソッドを呼び出す時は呼び出し元オブジェクトのスレッドを使って実行、一般オブジェクトのメソッドを呼び出す時は呼び出し先のスレッドを新規作成して実行)
- 一般子オブジェクトの作成
- 子オブジェクトの削除

さらに、特権オブジェクトに対しては追加で以下のAPIを提供します

- すべてのオブジェクトを対象にできるメソッド呼び出し
- すべてのオブジェクトを対象にできるオブジェクトの削除
- すべてのオブジェクトを対象にできる処理能力記憶能力の解放(剥奪)

# カーネルの構造
Shizukuはこのオブジェクトシステムを実現することに特化しているため、カーネルとしてはマイクロカーネルに近いですが、ビルド時に一部のコンポーネントを入れ替えてクロスプラットフォーム対応可能な構造に(一応)なってます。(これに1年溶かしました。もしSecHackに応募する人はターゲットアーキテクチャを絞ろうね！)

# 終わりに
SecHack365を通じて僕を支援してくださった方々へ感謝申し上げます。本当にありがとうございました。今年の一年はSecHack365で本当に実力も知識も伸びに伸びた一年となりました！みんなもSecHack365に応募しよう！！！
【JP1/AJS3】JP1 Managerログイン省略方法

## はじめに

複数のホストに接続することがあり、切り替えるのが地味に面倒だなぁーと思っていたら
実は、JP1のログインを省略する方法があったので記載しておく。

## やり方

１. 接続先設定ファイルを作成

`C:\Program Files (x86)\Hitachi\JP1AJS2V\conf\test.conf`
```test.conf　※ファイル名は何でもよさげ
username=ログインユーザー名
password=パスワード
host=接続先ホスト名
```

２. リンク先変更

JP1のショートカットのリンク先に
`"C:\Program Files (x86)\Hitachi\JP1AJS2V\bin\ajs.exe" -a test.conf`
と入力

３. JP1のショートカットを実行
ログインを省略して起動することができる！

<br/>
<br/>
<br/>
また、ピンポイントでジョブの状態、結果を開くこともできる。

##### ＜ジョブの結果＞
`"C:\Program Files (x86)\Hitachi\JP1AJS2V\bin\ajs.exe" -a test.conf -v monitor -m result -n AJSROOT1:/GYOUMU_GROUP1/PCジョブ`

ログインを省略しつつ、AJSROOT1:/GYOUMU_GROUP1/PCジョブの実行結果を表示することができる。
（ステータス監視のジョブネットモニタ＞結果と同じ）

##### ＜ジョブの状況＞
`"C:\Program Files (x86)\Hitachi\JP1AJS2V\bin\ajs.exe" -a test.conf -v monitor -m state -n AJSROOT1:/GYOUMU_GROUP1/PCジョブ`

-m をstateにすると、ログインを省略しつつ、AJSROOT1:/GYOUMU_GROUP1/PCジョブの実行状況を表示することができる。
（ステータス監視のジョブネットモニタ＞状況）


## 使用例）
・よく確認するホストのショートカットをこの設定にしておくだけで、時短になる。
・リリースや運用手順書に確認するJP1ジョブがある場合、ボタンを押したらピンポイントでJP1ジョブを確認でき、時短になる。
とか。


## 参考
> https://itpfdoc.hitachi.co.jp/manuals/3020/30203K2543/AJSO0012.HTM
embulk-input-bigqueryのインストールでエラー


以下を実行するとエラーが出た。

```sh
embulk gem install embulk-output-bigquery
```

Google関連サービスをインストールする時に起こるらしい。
例えば、以下のようなエラーが出る。
```sh
ERROR:  Error installing embulk-output-bigquery:
	representable requires Ruby version >= 2.4.0.
```


バージョンが合わないパッケージで、順次エラーが発生するので、下記のバージョンでインストールすれば解消される。
```sh
embulk gem install faraday -v 0.17.4
embulk gem install multi_json -v 1.15.0
embulk gem install jwt -v 2.3.0
embulk gem install public_suffix -v 4.0.7
embulk gem install addressable -v 2.8.6
embulk gem install signet -v 0.11.0
embulk gem install declarative-option -v 0.1.0
embulk gem install declarative -v 0.0.20
embulk gem install did_you_mean -v 1.0.1
embulk gem install uber -v 0.1.0
embulk gem install representable -v 3.0.4
embulk gem install retriable -v 3.1.2
embulk gem install mini_mime -v 1.0.2
embulk gem install memoist -v 0.16.2
embulk gem install multipart-post -v 2.1.1
embulk gem install os -v 1.1.4
embulk gem install googleauth -v 0.9.0
embulk gem install httpclient -v 2.8.3
embulk gem install google-api-client -v 0.32.1
embulk gem install google-cloud-env -v 1.2.1
embulk gem install google-cloud-core -v 1.3.0
```

参考記事。
- https://kkkw.hatenablog.jp/entry/2020/07/30/embulk-input-bigquery%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%A7%E3%82%A8%E3%83%A9%E3%83%BC
- https://github.com/embulk/embulk-output-bigquery/issues/144
- https://qiita.com/kaaaaaaaaaaai/items/6c2a459236ff2f714dc8
Javaで頻繁に変更される文字列を扱うならStringBuilderを使おう

# はじめに
最近leetcodeでプログラミングの問題を解いているのですが、実行時間をしっかりと気にしたほうが良いなと感じてきました。
もちろん問題がクリアできているかで言えばできてはいるのですが、それだと実践では良くないシチュエーションもあると思うので...
一番見落としがちなのがStringの変更だと感じたので今回記事にしました。
記事の中に含まれるコードではメソッドやクラスが省略されています。省略されているものは全部メインメソッドで実行されていると思ってもらって大丈夫です。

# Stringで文字列を更新する
至ってシンプルに書けるので、最初に学ぶ際にはシンプルで分かりやすいですね。
```Java
String s = "Good morning!";
s = "Good afternoon!";
s += " Yu-HaruWolf!";
System.out.println(s); // Good afternoon! Yu-HaruWolf!
```
実際このぐらいの変更しかないのであれば、まぁこれでも大丈夫かなという感じではあると思います。
問題は、大量に変更が加えられることがわかっている場合です。
試しにこんな感じのコードを作って実行してみました。
```Java
long start, end;
{
    start = System.currentTimeMillis();
    String string = "";
    for (int i = 0; i < 100000; i++) {
        string += "a";
    }
    System.out.println(string);
    end = System.currentTimeMillis();
}
System.out.println(end - start + "ms");
System.out.println(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
```
結果がこんな感じ。
```
aaaaaaaaaa...(省略)
411ms
57363160 (57.3MB)
```
「a」という文字列を10万回くっつける作業をしただけで0.4秒かかってしまいました。文字列をくっつけるのにこれだけかかっていると、ちょっと心配です。メモリも文字列を繋げるだけにしては使いすぎているように感じますね。

# StringBuilderで文字列を更新する
Stringで起きているような問題を解決することができるのが、StringBuilderです。
Stringでやっていたプログラムを再現するのであればこんな感じでしょうか。
Stringの時に比べ、メソッドの使用が発生しているので初めて学ぶ際は少しわかりづらいかもしれませんね。
```Java
StringBuilder sb = new StringBuilder("Good morning!");
sb.replace(5, sb.length(), "afternoon!");
sb.append(" Yu-HaruWolf!");
System.out.println(sb.toString());
```
さて次が本領発揮するところですね。
今度はStringBuilderを使って、こんな感じのコードを作って実行してみました。
```Java
long start, end;
{
    start = System.currentTimeMillis();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 100000; i++) {
        sb.append('a');
    }
    System.out.println(sb.toString());
    end = System.currentTimeMillis();
}
System.out.println(end - start + "ms");
System.out.println(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory());
```
結果がこんな感じ。
```
aaaaaaaaaa...(省略)
7ms
4867696 (4.86MB)
```
圧倒的に早くなって、メモリの使用量も削減されていますね。
このようなことから、文字列に対して大量の更新がかかることがわかっている場合は、StringBuilderを用いるのが無難そうですね。
なお、今回は比較してわかりやすくなるようにfor文を用いていますが、同じ文字を繰り返すだけであれば、こんな感じでrepeatメソッドを用いることができます。
```Java
s += "a".repeat(100000);
sb.append("a".repeat(100000));
```
なおこの場合はStringを使うほうが実行時間も使用メモリも少なく済みます。ただ同じ文字列を繰り返すだけのパターンは珍しいと思うので、基本的にはStringBuilderを使うのが良いでしょう。

# 原理
StringとStringBuilderの原理を考えるとこの結果になるのですが、その説明はこちらの記事がわかりやすいので是非こちらをご覧ください。

https://qiita.com/atsuk0r0/items/1208b5fead98676bc3c7

# 他にできること
新しいクラスでできることを知るにはJavadocを参照するのが一番確実だと思います。
是非メソッドの項を確認してみてください。

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/StringBuilder.html
Azure databricksのサンプルデータ

検証を行うさいに、検証環境へサンプルデータを投入するところが面倒だなと感じていましたが、Auzre databricksはデフォルトでサンプルデータがあることを知ったので備忘もかねて共有します。

本書ではUnity Cataloのデータセットのみ詳細を載せています。他のサンプルファイルを使った際はまた追記しようと思います。

参考サイト：[サンプル データセット](https://learn.microsoft.com/ja-jp/azure/databricks/discover/databricks-datasets)

### サンプルデータセットの種類
- Unity Catalogデータセット
- Databricksデータセット
- CSV 形式のサード パーティのサンプル データセット
- ライブラリ内のサードパーティのサンプル データセット


### Unity Catalogデータセット
”samples”カタログに3つのスキーマがあり、その配下にサンプルデータがある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269528/a25e66f0-1de9-4386-c78e-42c251d0ecf8.png)

レコード数等
| カタログ  | スキーマ  | テーブル   |  レコード数  |
|-----------|----------|------------|------------  |
| samples   | default  | -          | -|
|           | nyctaxi  | trips      |  21932  |
|           | tpch     | customer   |  750000  |
|           |          | lineitem   |  29999795|
|           |          | nation     |  25|
|           |          | orders     |7500000|
|           |          | part       |1000000|
|           |          | partsupp   |4000000|
|           |          | region     |5|
|           |          | supplier   |50000|

```sql
select
  (select count(*) from samples.nyctaxi.trips) as count_trips,
  (select count(*) from samples.tpch.customer) as count_customer,
  (select count(*) from samples.tpch.lineitem) as count_lineitem,
  (select count(*) from samples.tpch.nation) as count_nation,
  (select count(*) from samples.tpch.orders) as count_orders,
  (select count(*) from samples.tpch.part) as count_part,
  (select count(*) from samples.tpch.partsupp) as count_partsupp,
  (select count(*) from samples.tpch.region) as count_region,
  (select count(*) from samples.tpch.supplier) as count_supplier
```
Pythonで「キーワード引数を使って関数を呼び出す」の動作を確認してみた

# 概要

Pythonで「キーワード引数を使って関数を呼び出す」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/userfunc/index6.html

# 実装

以下のファイルを作成しました。
```sample.py
def myfunc(num1, str1):
    print("num1=" + str(num1))
    print("str1=" + str1)

myfunc(num1=10, str1="Orange")
myfunc(str1="Lemon", num1=15)

def myfunc(old, name, address):
    print("年齢は" + str(old) + "です。", end='')
    print("名前は" + name + "です。", end='')
    print("住所は" + address + "です。")

myfunc(28, "Suzuki", "Tokyo")
myfunc(address="Osaka", old=25, name="Yamada")
myfunc(32, address="Kyoto", name="Honda")
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
num1=10
str1=Orange
num1=15
str1=Lemon
年齢は28です。名前はSuzukiです。住所はTokyoです。
年齢は25です。名前はYamadaです。住所はOsakaです。
年齢は32です。名前はHondaです。住所はKyotoです。
```

# まとめ

何かの役に立てばと。
【知見メモ】端末の外観モードに合わせてキーボードの外観モードを変更できないケース

# 本記事について

端末の外観モードに合わせてキーボードの外観モードを変更できないケースについて紹介します。

## 環境

- iOS 17.0
- Xcode 15.2

# 調査概要

端末の外観モードに合わせてキーボードの外観モードを変更したいと要求がありました。
しかし前提として、info.plistのAppearanceをLightにしなければいけませんでした。
その条件でキーボードの色だけ外観モードに対応できるのか調査しました。

# 調査結果

- info.plistのAppearanceをLightにすると、端末の外観モードの設定関係なく、UITraitCollectionのuserInterfaceStyleが常に`.light`が返ってくる
- info.plistのAppearanceをAutomaticにすると、上記の問題は解決できるが、ダークモード対応していないアプリだと難しい。

```swift
final class SampleViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .lightGray

        // NOTE: UIの設定
        let textField = UITextField()
        textField.backgroundColor = .white
        textField.borderStyle = .roundedRect
        textField.placeholder = "入力内容"
        textField.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(textField)
        NSLayoutConstraint.activate([
            textField.widthAnchor.constraint(equalToConstant: 100),
            textField.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            textField.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])

        // NOTE: キーボードの外観を変えようとする
        // info.plistのAppearanceをLightだと、userInterfaceStyleは常に.light
        switch traitCollection.userInterfaceStyle {
        case .light:
            textField.keyboardAppearance = .light
        case .dark:
            textField.keyboardAppearance = .dark
        default: break
        }
    }
}
```
Route 53の利用に必要な基本知識

## はじめに
Route 53って、初心者にとってかなり難しくないですか？
何をしているのかイメージが湧きにくく、私もかなり苦戦しました。

そこで、Route 53に必要な名前解決の基本知識とともに、ざっくり解説したいと思います。

# DNSとは
DNS（Domain Name System）は、ホスト名とIPアドレスを紐づける仕組みです。

ホスト名からIPアドレスを求めることを名前解決といいます。
* 正引き：ホスト名からIPアドレス
* 逆引き：IPアドレスからホスト名

## DNSの構成要素
DNSは以下の要素で構成されています。
2024年現在、.co.jpサーバはjpサーバに統合されているため、下記の図は正確には正しくありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115411/430f1628-21c0-707a-930c-b2a3649aaf76.png)

# Route 53の概要
Route 53は、AWSが提供するDNSサービスです。

主な機能
* ドメイン名の登録と管理
* ホストゾーン
* リゾルバー
* ヘルスチェック

## Route 53 Resolver
Route 53 Resolverは、フルサービスリゾルバを提供します。

デフォルトでは、VPCを作成した時点でインターネット上のドメインに問い合わせをするリゾルバーが作成されます。
VPC内での名前解決や、オンプレミスと接続して名前解決を行う際に追加でリゾルバーを作成することが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115411/7141c913-df36-d9d6-83bd-9c4e186b4c71.png)

## Route 53 Hosted Zone
Route 53 Hosted Zoneは、 ゾーン情報を管理するため権威DNSにあたります。

ドメイン名の問い合わせに対して、どういう回答をするのかの設定をまとめたものです。
ドメイン名の問合せに対する回答について、ルーティングポリシーで設定可能です。
例）eample.comというドメイン名の問い合わせがあった場合に、11.11.11.11と22.22.22.22という2つのIPアドレスをランダムに返すようにする

### パブリックホストゾーン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115411/519f8b30-f271-f6cb-7c73-26d5625b7a3f.png)

### プライベートホストゾーン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115411/f32a5061-9889-f495-8df9-b20d0f7a2ea6.png)

## Route 53 ヘルスチェック
Route 53 ヘルスチェック機能は、エンドポイントの健全性を定期的にチェックし、障害が発生した場合にトラフィックを別のエンドポイントにルーティングできるようにする機能です。

Route 53 ヘルスチェックは、以下の方法でエンドポイントの健全性をチェックします。
* HTTP ヘルスチェック：エンドポイントにHTTP要求を送信して、応答コードが200であることを確認
* HTTPS ヘルスチェック：エンドポイントにHTTPS要求を送信して、応答コードが200であることを確認
* TCP ヘルスチェック：エンドポイントにTCP接続を試行して、接続が成功することを確認
* ICMP ヘルスチェック：エンドポイントにICMP要求を送信して、応答が返されることを確認


## おわりに
Route 53の基礎をわかると、一気に勉強がはかどりますね！
Power AutomateのPicture in Picture機能を試してみた

# はじめに

2024年2月、MicrosoftはPower Automate Desktopに待望の「Picture in Picture」機能を搭載しました。

# Picture in Picture機能とは？

Picture in Picture機能は、デスクトップフローをデスクトップ上の仮想ウィンドウ内で実行する機能です。これにより、ユーザーはデスクトップフロー実行中にも端末を占有されることなく作業を継続することができます。

今まではアテンド型にしろ非アテンド型にしろ、デスクトップフロー実行中は「さわるな危険」だったので、それが解消されることになります。

# Picture in Picture機能を使う前提条件
* Power Automate バージョン：2.4.1以降
* ユーザーは、Power Automateプレミアムまたは従量課金プランが必要です
* Picture in Pictureでデスクトップフローを実行するユーザーは、次の Windows ポリシーの一部である必要があります。
    * Computer Configuration\Windows Settings\Security Settings\Local Policies\User Rights Assignment\Allow Log On Locally
    * Computer Configuration\Windows Settings\Security Settings\Local Policies\User Rights Assignment\Access this computer from the network
* Windows 10 (Pro または Enterprise)、Windows 11 (Pro または Enterprise)、Windows Server 2016、Windows Server 2019、または Windows Server 2022 を実行するデバイス。

# Picture in Picture機能の使い方

Picture in Picture機能は、Power Automate Desktopのバージョン2.41以降で利用できます。この機能を使用するには、以下の手順に従ってください。

1. Power Automate Desktopを開き、フローを作成します。
1. フロー一覧画面に移動します。
1. 画面右上の「⋮」をクリックします。
1. 実行の「>」をクリックし、「Picture in Pictureで実行」を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4305/df349a97-b99d-6070-b198-df34a6afd31c.png" width=60%>

フローデザイナー画面から手動で実行する場合は、メニューの「デバック」が「ピクチャインピクチャモードを有効にする」を選択する必要があります。後は今までどおり「ここから実行」を選択するだけです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4305/88713002-2ad2-8213-f0a6-c735350bf27f.png" width=60%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4305/6af8ac09-3a20-a0ba-35f6-72dcac7c7105.png" width=60%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4305/0789dafe-1708-2754-ca54-76b189c94d81.png" width=60%>

# タスクスケジューラからPicture in Picture機能を使ってデスクトップフローを呼び出す方法

デスクトップフローはタスクスケジューラから呼び出すこともできますが、Picture in Picture機能を有効にした状態で呼び出すことも可能です。

フローのプロパティから「ローカルアテンド型の実行時の既定として設定」を有効にしておくと、PAD.Console.Host.exeをタスクスケジューラで起動した時にPicture in Pictureでデスクトップフローを実行してくれます。ちなみにこのプロパティ設定を有効にすると、フロー一覧画面での実行もPicture in Pictureで実行されることになります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4305/13006790-9e9e-1f43-78fe-6eaa89ffe979.png" width=50%>

ではこの「ローカルアテンド型の実行時の既定として設定」を有効にせず、PAD.Console.Host.exeに渡すオプションなどでPicture in Picture機能が有効に出来るかというと、正直方法がわからなかったです。

# Picture in Picture機能を使った所感
既存の複雑なデスクトップフローを試してわけではないですが、まず全体的に動作が重いです。仮想ウィンドウを起動するまでに時間がかかるのと、仮想ウィンドウを立ち上げた後にスタートアップで設定されているアプリも全て起動しますので、デスクトップフローが実行されるまでに時間を要します。そしてデスクトップフローの実行もメインで実行するより処理が重たいため時間がかかります。

Picture in Picture機能により確かにデスクトップフローによりりPCが占有されず他の作業ができるようになりますが、RPAとしてのデバッグ効率が非常に悪くなっているので、現状ではそれほどメリットは無いように感じます。

Picture in Picture機能まだプレビューとしての機能実装なので、今後改善されることを期待しましょう。

# 参考情報

* [Picture-in-Picture でデスクトップ フローを実行する (プレビュー)](https://learn.microsoft.com/ja-jp/power-automate/desktop-flows/run-desktop-flows-pip)
* [How to Use Picture In Picture mode in Power Automate Desktop(Youtube)](https://www.youtube.com/watch?v=lot7teGjhwM)
[React] カスタムダイアログの実装！(使用例)

# はじめに

前回は、Reactでカスタムダイアログを実装する方法を紹介しました！
今回は、前回のコードを改造し、簡単な使用例を追加してみたいと思います！

具体的には、確認ダイアログを搭載した、シンプルな名前登録アプリを作成してみます。
今回の実装では`CustomDialog.jsx`が必要となる為、前回の記事を参考に追加してから実施してみてください！

# 1. 登録確認ダイアログの作成

まず、登録確認ダイアログを作成します！
前回記事の`TestDialog.jsx`のcontentの中身とボタンのラベルをカスタムすることで作成できます！

```jsx
// components/UserRegistrationDialog.jsx
import React from "react";
import CustomDialog from "./CustomDialog";

export default function UserRegistrationDialog({
  isOpen,
  userName,
  onConfirm,
  onCancel,
}) {
  return (
    <CustomDialog
      isOpen={isOpen}
      content={`以下の内容で登録しますか？\n\n名前: ${userName}`}
      confirmButtonLabel="登録"
      cancelButtonLabel="キャンセル"
      onConfirm={onConfirm}
      onCancel={onCancel}
    />
  );
}
```

# 2. 名前入力と登録ボタンの作成
名前入力欄と登録ボタンを作成します！
入力された名前はReactのステートで管理します。

コンソールログに表示する処理をDBへ接続するAPIを呼び出すように改造すれば、名前登録アプリケーションの完成です！

```jsx
// pages/index.jsx
import { useState } from "react";
import UserRegistrationDialog from "../components/UserRegistrationDialog";

export default function HomePage() {
  const [userName, setUserName] = useState("");
  const [isConfirmationDialogOpen, setConfirmationDialogOpen] = useState(false);

  const handleNameChange = (event) => {
    setUserName(event.target.value);
  };

  const handleRegistration = () => {
    setConfirmationDialogOpen(true);
  };

  // 登録が押された時の処理
  const handleConfirmRegistration = () => {
    console.log(`${userName}さんが登録されました！`); // ここをDBへ登録する処理に変更
    setConfirmationDialogOpen(false);
    setUserName(""); // 入力欄の初期化
  };
  // キャンセルが押された時の処理
  const handleCancelRegistration = () => {
    setConfirmationDialogOpen(false);
  };

  return (
    <div>
      <label htmlFor="userName">名前：</label>
      <input
        type="text"
        id="userName"
        value={userName}
        onChange={handleNameChange}
      />
      <button onClick={handleRegistration}>登録</button>

      <UserRegistrationDialog
        isOpen={isConfirmationDialogOpen}
        userName={userName}
        onConfirm={handleConfirmRegistration}
        onCancel={handleCancelRegistration}
      />
    </div>
  );
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570986/7f5dc083-a681-6927-3a62-fd32808e82da.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570986/4cad20f6-06ad-9e51-edc6-f190bb229844.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570986/fe8a59af-1daa-e8c6-1305-b68225b8de04.png)


# まとめ

今回は、カスタムダイアログの使用例を紹介してみました！
今回の記事を参考に、各自のプロジェクトに追加してみてください！
ロジカルシンキングアウトプット

## 課題
上司にロジカルシンキングの方法をすすめられたため習得したい

## 結論
ロジカルシンキングの概要をまとめつつ、ロジカルシンキングを用いた記事を書く

## 根拠・判断基準
アウトプットすることで習得ができるようにするため

## ロジカルシンキングの概要
### 相手に伝えるべきメッセージとは
課題、根拠、相手のしてほしい反応を明確にすること
**成果を出すためにはまず課題を明確にすること。そして、相手に望む反応を考えること**

### ロジカルシンキングとは
問題に対して結論と根拠と方法が明確になっていること
さらに論理的に相手に伝えるうえで、漏れ、重複、ずれ、話の飛びがないようにする
これは相手に余計な作業（状況整理）をさせないためのもの

### 論理的な思考整理術

#### meceとは
重複・漏れ・ずれを防ぐ
項目ごとにグルーピングする。その際に、全て網羅している、抜け漏れがないようにする
とっかかりの例
4C→市場、競合、自社、チャネル

#### why so,so whatとは
飛びをなくす手法
so whatは問題に立ち返られるもの。それに対してwhy soで問題に対して結局何？なぜそのようなことができる？という具体的なやり方を導くもの

### 論理パターン

#### 並列型とは
同一階層に方法・根拠が相互にmeceな関係で構造化されている型
全体像を完結に説明したいとき使用するパターン
meceであることが重要
#### 解説型とは
事実→判断基準→判断内容の三つが根拠であり、結論とso what?/why so?の関係になっている型
事実が正しいこと、判断基準が妥当であること、が前提となる
相手に自分の結論の妥当性を強調したいとき、相手から助言を求めたいとき、結論のアクションを満たす方法が複数ある場合方法を選ぶ理由を説明するときに利用する

## 感想
自分の中で帰結してしまい、相手に伝えることが下手で幾度も注意を受けた人生でした
ロジカルシンキングを用いてうまく伝えられるようになったらいいと思います

### 参考文献
https://amzn.asia/d/fmAIyKB
Keycloak×Spring SecurityによるOIDC（Keycloak設定完了まで）

本記事は以下の記事を参考に、Keycloak×SpringSecurityによるOIDC実装を行った過程を備忘録として記事にしたものです。
参考: [Keycloak×Spring SecurityでOIDC入門](https://qiita.com/wtomioka-gxp/items/54c7c8e37b90a73cb52e)
## OIDCとは
OIDCとは OpenID Connect の略で、認可が目的だったOAuth2.0を拡張して認証も行えるようにした標準プロトコルです。
この仕様では、認証認可に使用するトークンの生成や受け渡しなどのフローを定められており、これに沿って認証認可を実現します。
ユーザーがアプリにログインすると、そのアプリは認証クライアントとして認証サーバーに認証を要求します。認証サーバーはユーザー認証を行い、IDトークンを発行してクライアントに返します。このIDトークンは、アクセスするための認証情報のことです。認証クライアントとなるアプリをRP（Relying Party）、認証を行うサービスをOP（OpenID Provider）といいます。

## Keycloakについて
Keycloakはオープンソースのソフトウェア（Identity Provider：idp）で、OIDCなどの標準プロトコルを実装しています。これによってシングルサインオンやAPIアクセスの認証・認可制御を実現できます。

ここからはKeycloakで認証サーバーを立てて、Spring Securityで保護されたアプリケーションの認証処理を実装していきます。

## Keycloakの構築
### dockerでコンテナとして起動
参考: [KeycloakのDockerセットアップ](https://qiita.com/KM9973/items/0d8b8e843d31ea8d3a7e)

### 管理コンソールで設定
クライアントとなるアプリ（＝認証したいアプリ）やユーザーの設定を行う。

#### レルム（Realm）
レルムは同一の認証情報やセキュリティ設定などが適用される範囲、同じ認証情報でシングルサインオンできる範囲です。クライアントとなるアプリやユーザーはレルム毎に設定することができます。
デフォルトで「master」という全てのレルムを包含して管理することができる特殊なレルムがあります。
「master」レルムはレルム内で最も高いレベルで、管理者(初回起動時に作成した管理者アカウント、ここでは環境変数で指定したアカウント)で管理できます。

まずはレルムを作成します。
管理コンソール左上のレルム名のプルダウン中の「Create Realm」ボタンから作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116202/f714b9b7-2561-9338-7f87-9db1be1f7fac.png)

任意のレルム名を設定します。（例：test-blog-app）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116202/ece61eb0-f1ac-de79-59e3-5d5f3c6212ac.png)

次に、クライアントとなるアプリを設定します。
左メニューの「clients」でクライアントの一覧を開き、「Create client」ボタンから設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116202/68039e11-bac3-3316-130f-1773715d64d0.png)

クライアントIDに任意の名前を設定（例：test-blog-app）、OIDCをするので、「Client type」が「OpenID Connect」になっていることを確認します。また、クライアントの身元証明を行うためにclient authenticationにチェックを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116202/6955e5bc-385f-7dae-c291-f1616a0921e6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116202/9edf075f-cdb7-33f9-a641-ece06a744bce.png)

クライアントの一覧から作成したクライアント（demo-app）を開き、Keycloakで認証した後にリダイレクト可能なURIを設定します。（例：http://localhost:8080/）

ユーザーを作成します。
左メニューの「user」でユーザーの一覧を開き、「Create new user」ボタンから作成します。
任意の「ユーザー名」を入力（例：test-blog-app-user）して作成します。

パスワードを設定するため、ユーザー一覧から作成したユーザーを開き、「Credentials」タブから設定します。
ここでTemporaryにチェックを入れると初回ログイン時にパスワード変更を要求されるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116202/3bcc22c8-bcdd-86d7-8f02-9e1ea9cd2b36.png)

## 次回の予定
次回の記事では、Spring Securityの設定していきます。現在、実装中ですので、完了次第記事にします。
Touch BarのMac×VSCodeのVimの相性が微妙に悪かったので改善した話

# 前提
私はVSCodeにVim拡張を導入してVSCode上でVimを使っています。

# 起こったこと
私のMacBookはTocuh BarなのでESCキーがありません。
なのでVimでノーマルモードに切り替えるには control + [ でノーマルモードに切り替える必要があります。
(これはデフォルトでキーバインドされていました)

https://scrapbox.io/craftmemo/MacBook_Pro_TouchBar_%E3%81%A7__Vim_%E3%81%AE_ESC_%E4%BB%A3%E3%82%8F%E3%82%8A

ですが、VSCode上でVimを使っているとちょっとした問題があります。

それは、
Mac版VSCodeはcontrol + ` (@キー)で　ターミナルに移動するショートカットがバインドされています。

そして、
`(@キー)の右横に[キーが配置されているんです。

これが何を意味するかというと、インサートモードで編集してノーマルモードに戻ろうとするとキーを押し間違えてターミナルに移動してしまうということが多発します。

事故ってほどではないですがめっちゃストレス。

# 解決方法
VScodeのショートカットの設定でターミナルへ移動するショートカットキーを変更することで解決しました。
（めっちゃ単純）

# ショートカットの変更方法
1.VSCode画面左下の歯車マークをクリックして「キーボードショートカット」を選択

![スクリーンショット 2024-03-01 17.42.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370336/46f8a374-0e83-5e47-43d7-db02e66aff5b.png)

2.めちゃくちゃいっぱいショートカットが出てくるので「入力してキーバインド内を検索」から「control + ` 」を検索
![スクリーンショット 2024-03-01 17.43.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370336/eda1fe8b-4e47-eff8-0f37-2ca55fe126a7.png)

3.該当するショートカットがあったら右クリックで「キーバインドの削除」

これでストレスフリーになりました😇
Gridのgapで後悔したこと


# gridって？ gapって？ 
<p class="codepen" data-height="300" data-default-tab="css,result" data-slug-hash="NWJaXLy" data-user="himeka223" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/himeka223/pen/NWJaXLy">
  Untitled</a> by himeka223 (<a href="https://codepen.io/himeka223">@himeka223</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

`grid` 
...子要素を見えないグリッドで仕切り、配置、サイズなど自由にできる
`gap` 
...子要素同士の余白を指定（gridの他にflexでも使える）

# どんな使い方で後悔したのか
親要素に子要素同士の余白を指定できるのが楽すぎて、`grid`を使わなくていいのに`gap`を使うためだけに乱用していた。下記みたいなときは、なんと3行も節約できちゃう！　
```SCSS:親にgapを使用
.area{
  display: grid;
  gap: 8px;
}
```
```SCSS:子にmarginを使用
.area{
  &__title{
    margin-bottom: 8px;
  }
  &__text{
    margin-bottom: 8px;
  }
  &__data{
    margin-bottom: 8px;
  }
  ...
}

```


# システム組込み時の新たなタグの出現
どこで後悔したかというと、初めてSalesforceのHTMLコーディグをしていたときのこと。
下記のようにシステム系のタグが入り、のちにHTMLタグとして出力するようで、`gap`が無効化してしまった。。。
```HTML:こんなとき
<div class="area">
  <システム系のタグ> 👈
    <h1 class="area__title">タイトル</h1>  
    <p class="area__text">テキストテキストテキスト</p>
    <div class="area__data">...</div>
  </システム系のタグ> 👈
</div>  
```
こうなってしまう箇所は少なかったので、ユーティリティで用意してた余白のみのクラスを追加して対応しました。

# システムを組込むときは`gap`の使い方は見直したほうが良さそう

純粋なHTMLだけでできてるコーポレイトサイトとかでは楽で便利だけど、管理画面のコーディングや、システムの組み込みのあるときは`gap`は相性が悪かったです。
あと共通エリアで指定して、余白が固定されてしまうと、汎用的でなくなり拡張性も悪くなります。（すべての使用箇所で完全に同じ余白であればむしろ揃うので良いかもしれない）

とりあえずは下記を意識するのが大事。

:::note warn
小さいパーツ（buttonとか）の中で使う
パーツ同士の余白には使わない
:::

システムに組み込まれる場合はどこに何が来ても崩れないマークアップが大事だなと実感しました。
同一ファイルの複数の変更を部分的にステージングする

`git add`コマンドは、指定したファイルに加えられた変更を全てステージングするためのコマンドです。  
ファイルの変更は１つのコミットとして記録されます。

しかし、`-p`オプションを使い`git add -p`として実行すると、指定したファイルに加えられた複数の変更を細かい単位で選択してステージングすることができます。

このようなステージング方法をパッチモードのステージングと呼びます。

複数の変更が１つのファイルにあり、それぞれ異なるコミットとして分割したいときに有効なコマンドです。

ターミナルとの対話的な操作を通して、パッチモードのステージングをするための手順を説明していきます。

1. 複数の変更が加えられたファイルを指定して`git add -p`を実行する

   ```shell
   git add -p <変更のあるファイル>
   ```

   すると、部分的な変更の差分と共に下記のように表示されます。

   ```shell
   (1/4) Stage this hunk [y,n,q,a,d,e,?]?
   ```

   「この変更部分をステージングしますか？」という意味です。

2. `[y,n,q,a,d,e,?]`の選択肢の中から行いたい操作を選んで Enter をクリックします。

   各選択肢の意味は次のとおりです。

   - `y`: この変更をステージングし、次の操作へ進む
   - `n`: この変更をステージングせずに、次の操作へ進む
   - `q`: この変更もこれ以降のどの変更もステージングせずに終了
   - `a`: このファイルの変更の内、この変更とそれ以降の変更を全てステージングして、次のファイルの操作へ進む
   - `d`: この変更部分もそれ以降の変更部分もステージングせずに、次のファイルの操作へ進む
   - `e`: エディタを開き、ステージングする部分をより細かく指定する
   - `?`: ヘルプを表示する

   この操作を続ければ OK です。

   `e`を選択した場合のエディタの操作について詳しく説明します。  
   `git diff`を実行した時と同じように変更の差分が表示されます。

   ```shell
   @@ -1,6 +1,6 @@
   function introduce(name: string, age: number): void {
   -  const sayName = "名前は" + name + "です。";
   -  const sayAge = "年齢は" + age + "歳です。";
   +  const sayName = `名前は${name}です。`;
   +  const sayAge = `年齢は${age}歳です。`;

     console.log(sayName + sayAge);
   }
   ```

   `-`が表示されている行は削除された変更です。この変更をステージングしたくない場合は、`-`をスペースに書き換えてください。

   `+`が表示されている行はコードの追加があった変更です。この変更をステージングしたくない場合は、この行を丸ごと削除して下さい。

   完了したら保存して終了してください。
Hello Worldからの復習 ～設計図クラス編～

前回はオブジェクト指向について簡単に復習したから今日は続き。

https://qiita.com/tianshandafu894/items/87c3aa267f6058dde8d1

おさらいとして、オブジェクト指向は2種類のクラスがあり、それぞれ、
**実行用クラス**
**設計図クラス**
があると確認。

んじゃ、どうやって書いていくかの基本的なところを復習開始。

##### お品書き
+ 設計図クラスって？
+ メソッドの定義

------

◆設計図クラスって？
-

設計図クラスには**属性**と**操作**を記述するが、この、属性、操作というのはオブジェクト指向の考え方の用語。

`※オブジェクト指向の用語とプログラミングの用語がごっちゃになると頭がパンクするので切り分けて覚えよう。`

そんで、
**属性**はプログラミングで**変数**を使って実現。
**操作**は**メソッド**を使って実現。

どう書くか。

```java:java
class クラス名{
     変数の定義
     ・
     ・
     メソッドの定義
     ・
     ・
}
```
**●変数の定義**

**データ型**　**変数名**
例：`String name;`
　　`int score;`

  宣言する場所がクラスのすぐ下。
  実行用クラスと違うね。

◆設計図クラスSample
-
  
```java:java
class Aaa{
//メンバー変数(属性)
//変数宣言はクラス名直下
  String name;
  int engScore;
  int mathScore;

//メソッド(操作)
void display(){
  System.out.println( name + "さん");
  System.out.println("英語" + engScore + "点・数学" + mathScore + "点");
}
void setScore(int eng, int math){
  engScore = eng;
  mathScore = math;
}
double getAvg(){
  double avg = (engScore + mathScore) / 2.0;
  return avg;
  }
}
```

※メンバー変数とは
mainクラスでも変数を設定したりするので、クラスがもつ属性としての変数のことをmainメソッドの変数と区別するためにメンバー変数と呼んだりする

◆メソッドの定義
-
```java:java
戻り値の型 メソッド名(引数リスト){
      (処理)
}
```

呼び出し元から受け取る値を**引数**
メソッドの処理の後に呼び出し元に返す値**戻り値**で、返す値は**return**で設定
何も返さない場合は戻り値の型に**void**を記述

```mermaid
graph LR
  main_display-->|引数なし|class_void_display
  class_void_display-->|戻り値なし|main_display
  main_setScore-->|引数あり|class_void_setScore
  class_void_setScore-->|戻り値なし|main_setScore
  main_getAvg-->|引数なし|class_double_getAvg
  class_double_getAvg-->|戻り値あり|main_getAvg

```

```java:java
class Aaa{
//メンバー変数(属性)
//変数宣言はクラス名直下
  String name;
  int engScore;
  int mathScore;

//メソッド(操作)
void display(){ //メソッドの()は必ずつける
  System.out.println( name + "さん");
  System.out.println("英語" + engScore + "点・数学" + mathScore + "点");
}
void setScore(int eng, int math){ //受け取り用の入れ物を用意。つまり変数宣言
  //受け取った値の代入
  engScore = eng;
  mathScore = math;
}
double getAvg(){ //少数点ありの平均点が欲しいのでdouble型
  double avg = (engScore + mathScore) / 2.0; // 演算子が/で/2にするとint型になるので2.0で計算
  return avg; //returnの後に返すデータと戻り値のデータ型を必ず合わせる。
  }
}
```
復習memo：変数の有効範囲はブロック内のみ。

作成したクラスはメインメソッドがないのでクラス単体では動かない。↓

```cmd:cmd
C:\Java\1>java Aaa
エラー: メイン・メソッドがクラスAaaで見つかりません。次のようにメイン・メソッドを定義してください。
   public static void main(String[] args)
またはJavaFXアプリケーション・クラスはjavafx.application.Applicationを拡張する必要があります

C:\Java\1>
```

疲れたので続きは次の復習にします。
CSSでPCとスマートフォンを区別

時々、違う設備によって、仕様も変わります。
その時は下記を参照してください

/* if device has a touch screen */
@media (any-pointer: coarse) {
    /* do your own styles */
    .css  class name{
        background-color:red; 
    }
}

/* if device has no touch screen */
@media (any-pointer: fine) {
    /* do your own styles */
    .css  class name{
        background-color:green; 
    }
}
白黒ランダムパターンを生成する。python

# 白黒のランダムパターンの生成
#### 研究で白黒のランダムパターンが必要になったのでPythonで作成しました。
```RP_1.py
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime

def generate_random_pattern(size=300):
    pattern = np.random.randint(0, 2, (size, size)) * 255

    return pattern

def save_pattern(pattern):
    filename = datetime.now().strftime("%Y%m%d%H%M%S") + ".png"
    plt.imshow(pattern, cmap='gray', interpolation='nearest')
    plt.axis('off')
    plt.savefig(filename, bbox_inches='tight', pad_inches=0)
    print("Pattern saved as:", filename)

pattern = generate_random_pattern()
save_pattern(pattern)
```
このコードはランダムなパターンを生成し、Matplotlibを使用して画像として保存します。
```RP_2.py
generate_random_pattern(size=300): 
```
この関数は、指定されたサイズのランダムなパターンを生成します。
サイズは、使うサイズによって変更してください。
```RP_3.py
save_pattern(pattern): 
```
この関数は、生成されたパターンを画像として保存します。
ファイル名は現在の日時に基づいて生成され、拡張子は".png"です。
生成した画像は、Matplotlibを使用して表示され、グレースケールで表示されます。
# google colabで実行
![スクリーンショット 2024-03-01 171044.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584275/29f966aa-bb14-15b4-ea84-4fc458e1cc4e.jpeg)
このようになります。是非使ってみてください。
Operatorのオーバーロード　

## 概要
C++で関数呼び出し演算子operator()をオーバーロードすることの役割は、オブジェクトを関数のように呼び出せるようにすることです。operator()をオーバーロードすることで、カスタム関数オブジェクト（ファンクタ）を作成し、オブジェクトにパラメータを渡して結果を返すことができます。

## 使用場面

### 関数オブジェクト（ファンクタ）
`operator()`をオーバーロードすることで、独自の関数オブジェクトを定義し、これらのオブジェクトを関数のように呼び出すことができます。
```c++
/*
Functor関数オブジェクト
*/

class Adder
{
public:
    // 関数オブジェクト
    int operator()(int a, int b) const
    {
        return a + b;
    }
};

int main()
{
    Adder add;
    std::cout << add(3, 4) << std::endl;  // 7
    return 0;
}

```

### ラムダ式
ラムダ式も本質的には***呼び出し可能なオブジェクト***であり、関数オブジェクトとして使用でき、アルゴリズムやSTLコンテナのメンバー関数に渡すことができます。
```c++
/*
ラムダ式
*/
int main()
{
    // 
    auto add = [](int a, int b)
        {
            return a + b;
        };
    std::cout << add(3, 4) << std::endl;  //  7
    return 0;
}

```

### 特定の機能を持つ呼び出し可能オブジェクトの実装
`operator()`をオーバーロードすることで、オブジェクトの動作を定義し、オブジェクトを呼び出して特定の操作を実行できます。この機能は、***ストラテジーパターン***、***イベント処理***、***コールバック関数***などのシナリオで非常に役立ちます。
```c++
/*
特定の機能を持つ呼び出し可能オブジェクトの実装
*/

class GreaterThan
{
    int threshold;

public:
    explicit GreaterThan(int threshold) : threshold(threshold)
    {
    }

    bool operator()(int num) const
    {
        return num > threshold;
    }
};

class LessThan
{
private:
    int threshold_{ 0 };

public:
    explicit LessThan(int threshold) : threshold_(threshold)
    {
    };

    bool operator()(int target) const
    {
        return target < threshold_;
    };
};

int main()
{
    std::vector<int> numbers = { 0,1, 2, 3, 4, 5 };
    auto count = std::count_if(numbers.begin(), numbers.end(), GreaterThan(3));
    std::cout << "Numbers greater than 3: " << count << std::endl;  //  2

    count = std::count_if(numbers.begin(), numbers.end(), LessThan(3));
    std::cout << "Numbers less than 3: " << count << std::endl;  //  3
    return 0;
}

```
[Google Sheets API] 行、列のサイズをデータに合わせる

Google Sheets API v4（Java）を使用して、
スプレットシートの行または列のサイズをセル内のデータサイズに自動で合わせる方法
についてご紹介します。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する](https://qiita.com/doran/items/3d43f776188b2281044c)
を参照ください。
```
例：requests.add(moveDimension(sheetId)); //実行したいリクエストのMethodを指定
```
:::

:::note info
その他のGoogle Sheets APIは、下記の記事を参照ください。
[⧉[Google Sheets API] JavaでスプレットシートのメニューとAPIを関連づけてみた](https://qiita.com/doran/items/2f6f8932b994fbd1a170)
:::

## 行、列のサイズをデータに合わせる
指定したセル範囲の行または列のサイズを
セルに設定されているデータのサイズに合わせて自動で変更します。

範囲(GridRange)の指定で
・範囲を指定しない場合、範囲はシート全体が対象
・終了行・列を指定しない場合、開始行・列からデータがある行・列までが対象
となります。

**サンプル コード**
シート全体に対して列のサイズを調整します。
```
public Request autoResizeDimensions(Integer sheetId) {
    Request request = new Request();

    DimensionRange range = new DimensionRange();
    range.setSheetId(sheetId);       //シートID
    range.setDimension("COLUMNS"); 	 //行(ROWS)か、列(COLUMNS)
    //range.setStartIndex(0); 		 //開始位置(0スタート)
    //range.setEndIndex(11); 	     //終了位置(1スタート)
    
    AutoResizeDimensionsRequest r = new AutoResizeDimensionsRequest();
    r.setDimensions(range);
    
    request.setAutoResizeDimensions(r);
    return request;
}
```
**実行結果**
この状態が
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/8558430b-38d5-0c47-bb3f-e2da65a4d76f.png">
列のサイズがデータに合わせてリサイズされました。
<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/2681df59-da83-271a-7a10-af7db61b2003.png">

<br>
おしまい。。
form_withのlocal:trueに関して

## はじめに
スクールの課題で、タスク管理アプリを作成しているときに、バリデーションが反映されない事象がありました。Railsのコンソールで、確認するとたしかにバリデーションのメッセージは出るのに、実際にブラウザ画面では出ませんでした。解決したのですが、備忘録として共有させていただきます。修正や追加等ありましたら、コメントいただけるとありがたいです。


## 環境
・MacBookAir 13インチ M1(2020)
・OS：Sonoma 14.3
・メモリ：16GB
・Rails： version 6.1.7.6

## エラーメッセージが出ない
```Rails
<%= form_with(model: task) do |form| %>
  <% if task.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(task.errors.count, "error") %> prohibited this task from being saved:</h2>
```
taskの新規登録のフォームで、バリデーションが通らなかった時にエラーメッセージをビューで表示したいと思いましたが、ブラウザで見てみるとエラーメッセージが表示されませんでした。

## やったこと
#### Railsコンソールでの要素が入っているかの確認。
![2024-02-27 16.30の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576805/97a8efa0-6cbd-0a62-6df3-f64b2468076e.jpeg)

バリデーションの設定自体はうまく行っていそう。
errorsやfull_messagesにもデータが入っていることを確認しました。
binding.irbを使っての他要素の確認も行いました。
tasks/controllersの確認も行いましたが、問題なさそうでした。

## 結論
```local: true```を追記。
```Rails
<%= form_with(model: task,　local:true) do |form| %>
  <% if task.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(task.errors.count, "error") %> prohibited this task from being saved:</h2>
```
```local: true```の設定がない場合、HTMLでdata-remote="true"の記載が追加され、Ajax通信（JavaScriptによる非同期処理）が行われるので、必要な箇所だけページが更新され、その他の箇所はそのままになるという事でした。そのため、エラーメッセージのHTML部分が加えられなかったと考えられました。
```local: true```と引数を渡す事で、これが通常のHTTPリクエストになり、ページ全体が返ってきてページがリロードされ、エラーメッセージも表示されるようになりました。

![2024-02-27 16.32の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576805/49d980ba-5c3a-c299-f8c8-84390bd40b6f.jpeg)


## 参考文献
https://qiita.com/kakudaisuke/items/e032c7705db00e8081dc
https://railsguides.jp/form_helpers.html
Visual Studio Codeで不要な音を鳴らさないようにする方法

## 原因

[Visual Studio Code 1.87](https://code.visualstudio.com/updates/v1_87)（2024年2月）で音声アクセシビリティ設定が刷新され、従来の `audioCues` と `accessibility.alerts` が `accessibility.signals` に統合されました。設定の移行時に既定値が変わり、操作のたびに効果音が鳴るようになったユーザーが多いように感じています。

また、2025年1月の [Visual Studio Code 1.97](https://code.visualstudio.com/updates/v1_97) では Copilot 連携を含む追加シグナル

```
accessibility.signals.save
accessibility.signals.lineHasFoldedArea
accessibility.signals.terminalQuickFix
accessibility.signals.lineHasInlineSuggestion
```

が導入され、通知音がさらに増えました。意義ある強化ですが、頻繁な音を煩わしいと感じる人もいると思います。

## 対策（2025/05/22更新）


### 1. コマンドパレット（`F1` または `Ctrl + Shift + P` / `⌘ + Shift + P`）で **List Signal Sounds** を実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3550646/3887431f-d946-447e-acad-778e05a314e4.png)


### 2. 必要なシグナルだけを選択して有効化・無効化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3550646/43c796bc-e6b8-47cc-ae47-50e8e4c4f325.png)


## 更新
### 2025/05/22
settings.jsonを編集する方法を紹介していましたが、スマートじゃないと感じていたのと、アクセスが増えたことをキッカケに他の方法を探したところ[VSCode Issue#211049](https://github.com/microsoft/vscode/issues/211049)で紹介されている方法がスマートだったので対策方法の記述を更新しました。
生成系AIに向けた質問の仕方

生成系AIを通じてとある分野について理解を深めるためには、以下の3つの観点から質問をすると効果的です。

**1. 事実に関する質問**

* 生成系AIは、この分野でどのような事実を生成できますか？
* 生成系AIは、この分野でどのようなデータに基づいて生成していますか？
* 生成系AIは、この分野でどのような精度で生成できますか？

**2. 洞察に関する質問**

* 生成系AIは、この分野でどのような洞察を提供できますか？
* 生成系AIは、この分野でどのような新しい発見を導き出すことができますか？
* 生成系AIは、この分野でどのような仮説を立てられますか？

**3. 創造性に関する質問**

* 生成系AIは、この分野でどのような新しいアイデアを生み出すことができますか？
* 生成系AIは、この分野でどのような新しい作品を生み出すことができますか？
* 生成系AIは、この分野でどのような新しい解決策を生み出すことができますか？

これらの質問例を参考に、具体的な質問をいくつか挙げてみましょう。

**例：**

* 生成系AIは、医療分野でどのような新しい診断方法を生み出すことができますか？
* 生成系AIは、金融分野でどのような新しい投資戦略を生み出すことができますか？
* 生成系AIは、教育分野でどのような新しい学習方法を生み出すことができますか？

生成系AIに質問をすることで、その分野に関する知識を深めるだけでなく、新しい視点やアイデアを得ることができます。

**その他、質問をする際のポイント**

* 具体的な質問をする
* オープンエンドな質問をする
* 創造的な質問をする
* 生成系AIの能力を理解した上で質問をする

生成系AIは、私たちの理解を超えた情報を生成することができます。積極的に質問をすることで、生成系AIの可能性を最大限に引き出しましょう。
Goインストール(goenv)

## 前提

anyenvがインストールされていること

## goenvをインストールする

```zsh
anyenv install goenv
```

```
exec $SHELL -l
```

## goenvを使ってGoをインストールする

ここでは最新バージョンのGoをインストールする

```zsh
go_version=$(goenv install --list | egrep -v 'rc|beta' | perl -pe 's/^ +([0-9]+\.[0-9]+\.[0-9]+)$/$1/' | tail -n 1)
```

```zsh
goenv install ${go_version}
```

```zsh
goenv global ${go_version}
```

```zsh
goenv rehash
```

```zsh
go version
```

```:出力
go version go1.22.0 darwin/arm64
```
セキュリティについて

## セキュリティに関する基本的な知識

セキュリティとは、情報資産の **機密性**、**完全性**、**可用性** を保護することです。

**3つの要素:**

* **機密性:** 許可されたユーザーのみが情報にアクセスできること
* **完全性:** 情報が改ざんされていないこと
* **可用性:** 必要なときに情報にアクセスできること

**主な脅威:**

* **マルウェア:** コンピュータに侵入し、情報を盗んだり、破壊したりするソフトウェア
* **フィッシング:** ユーザーを騙して個人情報を盗み取る攻撃
* **ソーシャルエンジニアリング:** 人間心理を利用して、ユーザーを騙し、情報を盗み取る攻撃
* **DoS/DDoS攻撃:** サーバーに過剰なアクセスを行い、サービスを停止させる攻撃

**基本的な対策:**

* **パスワード管理:** 強固なパスワードを設定し、定期的に変更する
* **ソフトウェアのアップデート:** 最新のセキュリティパッチを適用する
* **ファイアウォールの利用:** 不正なアクセスを遮断する
* **アンチウイルスソフトの利用:** マルウェアからコンピュータを守る
* **従業員教育:** セキュリティに関する意識を高める

## セキュリティ分野を完全にマスターするための方法

**1. 基礎知識を習得する**

* セキュリティに関する書籍やオンライン教材で基礎知識を学ぶ
* 資格取得を目指す (例: 情報処理安全確保支援士)

**2. 実践的なスキルを磨く**

* セキュリティツールの使い方を学ぶ
* 脆弱性診断やペネトレーションテストなどの実践的な演習を行う
* CTF (Capture the Flag) などのセキュリティコンテストに参加する

**3. 最新情報を常にキャッチアップする**

* セキュリティ関連のニュースやブログを定期的に読む
* セキュリティカンファレンスや勉強会に参加する

**4. 専門性を深める**

* クラウドセキュリティ
* アプリケーションセキュリティ
* ネットワークセキュリティ
* インシデント対応

**参考資料:**

* IPA 情報処理推進機構: [https://www.ipa.go.jp/](https://www.ipa.go.jp/)
* JPCERT/CC: [https://www.jpcert.or.jp/](https://www.jpcert.or.jp/)
* SANS Institute: [https://www.sans.org/](https://www.sans.org/)

**その他:**

* セキュリティは常に進化している分野なので、継続的な学習が重要
* コミュニティに参加して、情報交換や相互学習を行う
* セキュリティに関する倫理観を持つ

**セキュリティは、現代社会において非常に重要な課題です。**

上記の情報を参考に、セキュリティに関する知識を深め、スキルを磨き、情報資産を守りましょう。