OmniAICreator/Qiita-1.07M huggingface dataset:
AWSの更新情報をメールで受け取る（AWS Daily Feature Updates）

AWSが提供する各種サービスの最新情報をいち早くキャッチしたいとお考えの方は、AWS Daily Feature Updatesを利用して、各サービスの更新情報をメールで受け取ることができます。この記事では、その設定方法を詳しく解説していきます。

参考リンク：[AWS Daily Feature UpdatesをAmazon SNSで購読](https://aws.amazon.com/jp/blogs/news/subscribe-to-aws-daily-feature-updates-via-amazon-sns/)

## 設定方法

### 1. SNS サブスクリプションの作成

まずはじめにSNSサブスクリプションを作成します。ここではAWS CLIで設定してみます。  
  
以下のコマンドを実行して、指定したメールアドレスに更新情報を送信するように設定してください。topic arnには [arn:aws:sns:us-east-1:692768080016:aws-new-feature-updates] を指定します。

```aws
aws sns subscribe --topic-arn arn:aws:sns:us-east-1:692768080016:aws-new-feature-updates --protocol email --notification-endpoint sample@example.com --region us-east-1
{
    "SubscriptionArn": "pending confirmation"
}
```

### 2. サブスクリプションの確認

コマンドを実行した後、設定したメールアドレス宛に「AWS Notification - Subscription Confirmation」というタイトルのメールが送られます。メール内にある「Confirm subscription」のリンクをクリックし、サブスクリプションの確認を行ってください。

### 3. 更新情報の受信

サブスクリプションが確認されると、AWSの更新情報がある日には、「What's NEW today for your AWS account」という件名でメールが送られてきます。メール内には、更新情報がJSON形式で記載されており、HTMLで表示できるリンクも同梱されています。

これで、AWSの各サービスの最新情報をメールで受け取ることができるようになりました。ぜひ、この機能を活用して、AWSのアップデート情報を逐一チェックしましょう！
paiza.ioでelixir その235

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

# 練習問題
モジュールをセーブして、ロードして実行せよ。

# サンプルコード

```

s = "defmodule M do\n def add(a, b) do\n a + b\n end\n end"
:ok = File.write("M.exs", s)
|> IO.inspect

File.ls!
|> IO.inspect

{:ok, code} = File.read("M.exs")
Code.eval_string(code)
M.add(5, 4)
|> IO.inspect




```

# 実行結果

```
:ok
["main.tar.gz", "Main.exs", "runner_mysql", "exec_stdin.txt", "run_user",
 "runner_php", "exec_stderr.txt", "exec_command", "M.exs", "exec_stdout.txt"]
9

```

# 成果物

https://paiza.io/projects/ykAG840hrnpO7b_Wa_dnBQ


以上。
Login IP Ranges の設定


+ [How can I restrict Login IP Ranges for single user?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Pf7uN)

権限セットではできない。

:::note
Looks like this is still an idea:

Use Permission Sets to Assign Login IP Ranges
https://ideas.salesforce.com/s/idea/a0B8W00000Gdp8gUAB/use-permission-sets-to-assign-login-ip-ranges


Unfortunately there is no option to define Login IP ranges on a user or at permissions set level. As a workaround you can create a custom profile by cloning the existing one and set loign ip ranges on that and assign it to this user.
:::
全エンジニアに依頼！リモートワークやめよう！

近年、新型コロナウイルスの影響により、リモートワークが急速に普及しました。
コロナは色々な影響を我々に与えました。パンデミックになりましたがネット上のリテラシー、技術は格段に進化し、浸透しました。
しかし全エンジニアに提言です！

# 全エンジニアに依頼！　リモートワークやめよう！

リモートワークには確かにメリットがあります。シニアエンジニアにとっては、効率的な作業が可能であり、通勤時間の節約や柔軟な働き方の実現など、多くの利点があります。しかし、若手エンジニアにとっては、オフィスで働くことによって得られる利益が存在します。

# 「一体感」と「心理的安全性」

会議ツールやコミュニケーションツールの進化によって、エンジニアの作業はリモート環境でもスムーズに進められるようになりました。しかし、実際には同じ場所で作業することによって生まれる「一体感」と「心理的安全性」が、成長する若手エンジニアにとって非常に重要な要素であることを忘れてはなりません。

まず、オフィスでの作業は、仲間との一体感を高める効果があります。同じ空間で働くことによって、チームメンバーとのコラボレーションや情報共有がスムーズに行えます。デスクの近くに座っている先輩エンジニアを見て、彼らの作業を通じて学ぶことができるのも大きなメリットです。リモートワークでは、これらの貴重な学びの機会が減少してしまう可能性があります。

さらに、オフィスでの雑談や近くの会話から生まれる新しい情報やアイデアは、成長するエンジニアにとって重要な刺激源です。リモート環境では、コミュニケーションが主に業務に関連したものに偏ってしまいがちですが、非公式な場での交流やアイデアの共有が持つ効果は計り知れません。オフィスでのエンカウントが、若手エンジニアの創造性やイノベーションに繋がることは間違いありません。

一方で、シニアエンジニアにとっては、リモートワークのメリットがより顕著に現れることも事実です。経験と知識が豊富な彼らは、一人で集中して作業を進めることができるため、自宅や好きな場所での仕事が効率的です。しかし、彼らも若手エンジニアの成長を支援する役割を果たしており、オフィスでのプレゼンスは、若手エンジニアにとっての良い影響を与えることができます。

# まとめ
コロナでリモートワークになり、会議ツールとかコミュケーションツールが進化してリモートワークでエンジニアの作業は問題なく進めれてる様に感じてますが、実際は、同じ場所で作業することにより、仲間との一体感を感じて心理的安全性が構築されたり、憧れの先輩エンジニアをみてモチベートされたり、雑談や近くの会話から新しい情報、仲間とエンカウントされたりします。

若手エンジニアにとっては、これらの要素は成長していくためにとても重要なものになります。
もちろんシニアエンジニアは、その辺りは不要でリモートワークの方が効率的ではありますが、出社する事で若手エンジニアに良い影響を与えることができます

そろそろリモートワークやめてみてはいかがでしょうか？ 

# 最後に
エンジニアの皆さん、エンジニア未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
Quote Line Editor


+ [Amending Large Contracts](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000QO7dN)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/10e942d8-fcda-10aa-d215-1bae199c57db.png)


Infinite Loading Quote Line Editor
https://issues.salesforce.com/issue/a028c00000qQ5B0AAK/infinite-loading-quote-line-editor

Salesforce CPQ Quote Line Editor has infinite load
https://help.salesforce.com/s/articleView?id=000382401&type=1

Please check out the below package settings related to amending the large contracts-

1. SF CPQ Package Settings ->  Subscriptions and Renewals ->  Legacy Amend/Renew Service

2.   SF CPQ Package Settings ->  Subscriptions and Renewals ->  Amend Contracts in Background 

:::note
. I was able to find out that the Amendment Opps were getting created however we had QLs not linked to QLGs and that is what was causing the Infinite loading issue on the Quote Configurator screen.

Amendment Opps が作成されていることがわかりましたが、QL が QLG にリンクされておらず、それが Quote Configurator 画面での無限ロードの問題の原因となっていました。
:::

+ [Hiding default CPQ Quote Line Editor fields?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A90u6SAB)

:::note
For Quote level fields on the Quote Line Editor, you should look at the field set SBQQ__LineEditor on the Quote object.
 

For Quote Line Group level fields, you should look at the field set SBQQ__LineEditor on the Quote Line Group object.
:::

+ [Remove info icon from Quote Line editor](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007MwaSwSAJ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/dbb052a5-9763-c790-9fe5-bdffe3d886ee.png)

+ [Quote Line Editor の一番右に表示される「削除」オプションの表示を制御するにはどうすればよいですか。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A8NUYSA3)

:::note
Later informed the BA's that removing those info icons are not possible.
:::
Ruby 3.2を使ってRailsアプリのViewファイル（ERB）のカバレッジを測定する方法

## はじめに
今回は、Ruby3.2の新機能を使ってRailsアプリケーションでViewファイル（ERB）のコードカバレッジを計測する方法についてご紹介します。
ここでは、[SimpleCov](https://github.com/simplecov-ruby/simplecov)というカバレッジツールを使用して、Ruby3.1まで出来なかったViewファイル（ERB）のカバレッジを計測する方法を説明します。

## 前提条件
- Ruby 3.2
- [SimpleCov](https://github.com/simplecov-ruby/simplecov) 導入済み
- ViewファイルをERBで記述している

## Simplecovの設定例

以下を参考にSimpleCovの設定内容を見直していただければ、Viewファイル（ERB）のコードカバレッジが計測されるようになります。

```ruby:.simplecov
SimpleCov.start('rails') do
  # この設定を追加することでERBファイルのカバレッジ計測が有効となる
  enable_coverage_for_eval

  # いい感じにグループ分けされるようにViewsのグループ定義を追加
  add_group 'Views', 'app/views'

  # 未実行ファイルの存在を検出するために対象となるERBファイルをGLOB指定
  # この設定を足すことでテストを全く通っていないERBファイルについてもカバレッジ0%として検出されるようになります
  track_files 'app/**/*.erb'
end

# ERBファイルの場合の不要な警告抑制のためのパッチ（無くても動作的には問題ありません）
# https://github.com/simplecov-ruby/simplecov/issues/1057
SimpleCov::SourceFile.prepend(Module.new do
  private

  def coverage_exceeding_source_warn
    return if @filename.end_with?('.erb')

    super
  end
end)
end
```

## 実行結果の例
![Demo](https://user-images.githubusercontent.com/21557/205423930-6ee3116d-d04b-49c7-91e7-3a0a123c5848.png)

## 終わりに
Viewファイル（ERB）のコードカバレッジについても計測対象とすることで、開発者がアプリケーションのテスト品質をより把握することが出来るようになるかと思います。
既にSimpleCovとERBを利用しているプロジェクトの場合は、設定を有効にすることを検討してみてはいかがでしょうか。

## 参考記事
- [Ruby 3\.2でERBテンプレートのカバレッジが測れるようになるぞ\!\! \(1\) eval, ERB 編 \| Wantedly Engineer Blog](https://www.wantedly.com/companies/wantedly/post_articles/437514)
- [Ruby 3\.2でERBテンプレートのカバレッジが測れるようになるぞ\!\! \(2\) SimpleCov, Rails View ファイル編 \| Wantedly Engineer Blog](https://www.wantedly.com/companies/wantedly/post_articles/440752)
- [Evaluating More Coverage in Ruby 3\.2 \- Kevin Murphy](https://kevinjmurphy.com/posts/evaluating-more-coverage-in-ruby-3-2/)
- [Support coverage for eval by mame · Pull Request \#1037 · simplecov\-ruby/simplecov](https://github.com/simplecov-ruby/simplecov/pull/1037)
【Git】gitignore がなぜか反映されない問題、既に tracked だからでした

# 🎯 結論
gitignore で実現できるのは
『**未追跡 (untracked) のファイルに対して無視を決め込むこと**』であって
『追跡 (tracked) されているファイルを未追跡 (untracked) にすること』ではない。

だから、既に tracked なファイルは
(例：一度 git add してステージングしたことのあるファイル)
**後から .gitignore に追加しても意図通りに無視されない。**

既に tracked なファイルについては
`git rm --cached {file_path}` コマンドを使用して
指定したファイルを [tracked (追跡) → untracked (未追跡)] にすることで
**git の追跡対象から外す**ことができる。

# 🔍 詳細
自分の備忘録も含めた内容となっており
気張らずゆるく書いた内容ですので悪しからず🙏

### 経緯

僕は GoogleAppsScript の開発をするに際して、
いつも[ローカルで GoogleAppsScript の開発を行えるテンプレート](https://github.com/matcher-inc/gas-template)を使用しています。
(自分で作ったやつです)

:::note info
こちらの記事でも紹介しておりますのでよろしければご覧ください。
[**【TypeScript + Webpack】今すぐ誰でも、ローカルで GoogleAppsScript の開発を始められるテンプレート (初心者向け)**](https://qiita.com/Ryo-Nakano/items/50366600543c2888ada7)
:::


本来は GAS プロジェクトを TypeScript で開発するために作ったものですが、
最近は TypeScript はめっきり使わなくなり
ただの『ローカルで GoogleAppsScript の開発を行えるテンプレート』に成り下がっています。

--

そんなテンプレートをいつも通り github から　clone して
開発を行なっていたところ事件が起きました。

(これまでも同様の事件は起きていたのですが「変だなあ...」と思いつつ無視していました)

### 起きていたこと

.gitignore ファイルの中で変更を追跡してほしくないファイルを指定していたが
なぜか変更が追跡され続けていた。
(具体的には .clasp.json というファイル)

### 問題
.clasp.json は git 管理下に置きたくないのに **git に変更が追跡されてしまっている**。

自分で気をつけて commit, push しなければいいだけの話かもしれないが、
そこに気を張り続けるのも疲れるし、何より人間である私がいつミスをしでかすか分からない。

↑ こういった悩みを解消するために .gitignore ファイルで
.clasp.json を追跡対象から外すように設定したにも関わらず、
変更が追跡され続けているのは**誠に遺憾**。


### 原因
.clasp.json が既に tracked なファイル
(例：一度 git add してステージングしたことのあるファイル) であること。

.clasp.json は github から clone してきたプロジェクトの中に存在しているわけですから、
tracked なファイルであることは自明です。


### 解決策
`git rm --cached {file_path}` コマンドを利用して
指定したファイルを [tracked (追跡) → untracked (未追跡)] にすることで
**git の追跡対象から外す**。

そうすると、ちゃんと gitignore が効くようになる。
( gitignore で実現できることは『未追跡 (untracked) のファイルに対して無視を決め込むこと』だから)



# 📚 参考
- [gitignore を正しく理解したい](https://kmyk.github.io/blog/blog/2020/11/08/man-gitignore/#gitignore-%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%A7%E3%81%82%E3%82%8B%E3%81%8B)
- [[Git] .gitignoreの仕様詳解](https://qiita.com/anqooqie/items/110957797b3d5280c44f#gitignore%E3%81%AB%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%97%E3%81%9F%E3%81%AE%E3%81%AB%E7%84%A1%E8%A6%96%E3%81%95%E3%82%8C%E3%81%AA%E3%81%84)
- [gitignore の除外が反映されない時の対処方法](https://www-creators.com/archives/6144)
- [git rm --cached ファイルをリモートリポジトリのみ削除する](https://zenn.dev/msksgm/articles/20211108-git-rm-cached)
We couldn’t send invitation emails for the <SurveyID> survey to one or more recipients: <ContactID>



+ [Survey Invitation Issues](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000QOGcS)

:::note
I wish I had a better answer here, but my issue was resolved after disabling/enabling surveys in the 'Survey Settings'. I submitted a ticket with SF, but they weren't much help. 

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000KeXDBSA3

ここでもっと良い答えがあればよかったのですが、「調査設定」で調査を無効/有効にしたことで問題は解決しました。 SF にチケットを提出しましたが、あまり役に立ちませんでした。
:::

I think I figured out our issue, at least all of the failure examples I've seen from our service group are for contacts with related user records that are inactive. Still not 100% positive as to this though as surveys seem to be sending fine for contacts who don't have user records. 

私たちの問題は理解できたと思います。少なくとも、私たちのサービス グループで確認したすべての失敗例は、非アクティブな関連ユーザー レコードを持つ連絡先に関するものでした。ただし、ユーザー記録を持たない連絡先にアンケートが送信されているようであるため、これに関してはまだ 100% 肯定的ではありません。
レコードトリガーフローでは画面を起動できない


+ [取引先責任者の項目を更新した際に、新規で商談レコードを作成したい](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000QMUgX)

取引先責任者の項目をとある項目にした際に、商談作成画面が表示されるようなフローを組みたいのですが、クイックアクションや画面フロー等で実現することは可能でしょうか？

:::note
標準の機能でレコードの更新から画面を起動させることはできないと思います。

画面に項目のないカスタムコンポーネントを作って、取引先責任者の更新時のトーストイベントを取得したときにrecordIdを取得して 取引先責任者 のある項目をチェックします。

商談を作る必要がある条件なら、このカスタムコンポーネントのコントローラから画面フローに遷移すれば起動できると思います。またモーダルのカスタムコンポーネントやクイックアクションも起動可能です。
:::
Bootstrapをオフライン環境で使用する方法

# はじめに
Bootstrapは\<head>内に下記を追加するだけで使用できますが、こちらはCDNを利用した方法のためオフライン環境では使用することができません。
```<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">```

オフラインで利用する場合は、Bootstrapの資材をダウンロードしてインストール作業等行う必要があります。
公式サイトにも手順が記載されていますが、個人的に分かりにくいと感じたので、こちらで手順をご紹介します。

# 前提条件
本手順はリリース前の環境構築段階でインターネット接続できる状態を想定しています。
環境構築段階で既にオフライン状態である場合は、下記リンクの「コンパイルされた CSS と JS」のダウンロードボタンよりローカル環境にBootstrapを入手し、SCP等で転送して利用してください。
https://getbootstrap.jp/docs/5.0/getting-started/download/

また下記手順はCentOS7で実施しています。

# Composerのインストール
今回パッケージマネージャはComposerを利用します。
下記コマンドによりComposerをインストールします。

```
# curl -sS https://getcomposer.org/installer | php
# mv composer.phar /usr/bin/composer
# composer -V
```

composer -V でバージョンが表示されたらインストール成功です。

# Bootstrapのインストール
先程インストールしたComposerを利用してBootstrapをインストールします。
ComposerでBootstrapをインストールする際、zip、unzipコマンドを使用するためこちらを事前にインスールしてください。
その後、Bootstrapを配置したいディレクトリに移動して、インストールコマンドを実行します。

```
# sudo yum install -y zip unzip
# cd /var/www/html/
# sudo composer require twdb/bootstrap:5.0.0-beta1
```

# html上での指定の仕方
\<head>内に下記のように相対パスで記載すれば使用することができます。

```
<link href="vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
```
React Nativeのstart時にエラー

npx react-native start
コマンド実行時に下記のようなエラーが出た。

failed to construct transformer envelope routines::unsupported

digital envelope routines::initialization error

そのため、npx react-native run-androidを実行すると、Androidの仮想デバイスも赤いエラー画面が出力。

調べたところ、どうやらnode.jsのバージョンがいけないらしい。
自分が使っていたのは最新バージョンの17.3.0
v17でこのエラーが発生するようなので、安定バージョンの16.13.1にダウングレードすることで解決しました。

ちなみにnode.jsのダウングレードはWindowsだとコントロールパネルからnodejsをアンインストールして、
node.js公式から16.13.1をダウンロードして、インストーラを走らせるだけ。
【Eclipse】環境設定まとめ

Java開発を始めてEclipseを使うようになったのですが、
設定項目が多くて迷うことがあるので備忘録として残しておきます。

# Java
`[ウィンドウ]`－`[設定]`の`[Java]`－`[インストール済みのJRE]`
`[ウィンドウ]`－`[設定]`の`[Java]`－`[コンパイラー]`　
※ワークスペース個別設定プロパティでは`[Javaコンパイラー]`

 **新規プロジェクト作成時に設定する場合**
`[Java プロジェクトを作成します。]`画面の「JRE」欄で`[プロジェクト固有のJRE を使用]`にチェックを入力し、任意のJRE を選択する。

 **既存プロジェクトのJavaを変更する場合**
プロジェクトを選択し、右クリックのメニューより`[プロパティ]`を選択する。
プロパティ画面の左ペインより`[Java のビルドパス]`を選択し、
`[ライブラリー]`タブの`[JRE システムライブラリー]`で任意のJRE に変更する。

# エディタ
　行番号の表示
`[ウィンドウ]`－`[設定]`の`[一般]`－`[エディタ－]`－`[テキスト・エディタ]`

　未使用のimport文を削除
`[ウィンドウ]`－`[設定]`の`[Java]`－`[エディター]`－`[保存アクション]`
「保存時に選択したアクションを実行」にチェック
「インポートの編成」にチェック

# Maven
`[ウィンドウ]`－`[設定]`の`[Maven]`－`[ユーザー設定]`
Mavenでプロキシを利用する際などにsettings.xmlの場所を指定

# その他
タスク・タグ
`[ウィンドウ]`－`[設定]`の`[一般]`－`[エディター]`－`[構造化テキスト・エディタ－]`－`[タスク・タグ]`

ローカル・ヒストリー
`[ウィンドウ]`－`[設定]`の`[一般]`－`[ワークスペース]`－`[ローカル・ヒストリー]`
ファイル保持日数・最大ファイルサイズ etc..

コード・テンプレート
`[ウィンドウ]`－`[設定]`の`[Java]`－`[コード・スタイル]`－`[コード・テンプレート]`
自動生成させるコメントやコードを設定
脆弱性管理のベストプラクティス：中小企業向け

中小企業における脆弱性管理は、潜在的なサイバー脅威からの保護において重要な役割を果たします。今日のデジタル環境では、サイバー攻撃がますます洗練されているため、効果的なプラクティスを採用し、機密情報を保護し、顧客の信頼を維持し、財務的な損失を防ぐために、中小企業はセキュリティポストを強化しリスクを効果的に軽減する必要があります。本記事では、中小企業における脆弱性管理のベストプラクティスに関する貴重な洞察を提供し、セキュリティの状況を向上させ、リスクを効果的に軽減することができるようにします。

このトピックについてもっと知りたい場合は、ここに私のソースがあります-https://www.mend.io/resources/blog/vulnerability-management/

1. イントロダクション

このセクションでは、中小企業における脆弱性管理の重要性について説明し、本記事の内容について概説します。中小企業はしばしば大企業と比べてリソースが不足しているため、効率的な脆弱性管理プラクティスの実施はさらに重要です。

2. 脆弱性の理解

ベストプラクティスに入る前に、まずは脆弱性の定義と、中小企業が直面する一般的なタイプを理解することが重要です。本セクションでは、脆弱性の定義を示し、ソフトウェアの非最新化、弱いパスワード、誤った設定などの例を取り上げ、ビジネスに潜在的なリスクをもたらす可能性があるものを議論します。

![Vulnerability-managment-process-image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475999/5d75116a-2d83-6f30-24d3-c7046e2227a0.png)


3. リスクの評価と脆弱性の優先順位付け

脆弱性管理を効果的に行うためには、まず脆弱性評価を行うことが重要です。本セクションでは、リスクの評価、潜在的な影響の評価、および重大度に基づいた脆弱性の優先順位付けについて指南します。重要な脆弱性に重点を置くことで、ビジネスはリソースを効果的に割り当てることができます。

4. 脆弱性管理計画の作成

包括的な脆弱性管理計画の作成は、積極的なセキュリティアプローチの基盤を築きます。本セクションでは、目標の設定、役割と責任の明確化、計画の範囲の定義、適切なツールとテクノロジーの実施の重要性について説明します。

5. 定期的なパッチ適用とアップデート

ソフトウェアを最新の状態に保つことは、脆弱性を最小限に抑えるために重要です。本セクションでは、定期的なパッチ適用とアップデートの重要性、パッチ管理プロセスの実施方法、および可能な限り自動化することの利点について取り上げます。

6. ネットワークセキュリティ対策

ネットワークインフラの保護は中小企業にとって重要です。本セクションでは、ファイアウォールや侵入検知システムの導入、異常なネットワークトラフィックの監視などの対策について議論します。これらのセキュリティ対策を実施することで、ビジネスは潜在的な脅威からネットワークを強化することができます。

7. 社員のトレーニングと意識向上

社員は組織のセキュリティにおいてしばしば最も脆弱な部分です。本セクションでは、社員にセキュリティのベストプラクティスを教育し、ソーシャルエンジニアリング攻撃に対する意識を高め、セキュリティ意識のある文化を醸成することの重要性を強調します。社員を力に変えることで、ビジネスは人為的な脆弱性のリスクを大幅に減らすことができます。

8. インシデント対応と復旧

予防策を講じていても、インシデントは発生する可能性があります。本セクションでは、中小企業がインシデント対応計画を作成し、効果的なコミュニケーションチャネルを確立し、インシデント後の分析を行う方法についてガイダンスを提供します。タイムリーな対応と復旧はセキュリティインシデントの影響を最小限に抑えるために重要です。

9. サードパーティのリスク管理

中小企業はしばしばサードパーティのベンダーに頼ることがあり、これにより潜在的な脆弱性にさらされる可能性があります。本セクションでは、サードパーティのベンダーと関連するリスクの評価と管理の重要性、関与する前のデューディリジェンスの実施、およびベンダーのセキュリティプラクティスの監視について説明します。強固なセキュリティエコシステムを確保するためにこれらの手法を活用します。

10. 継続的な監視と改善

継続的な監視ソリューションの実装により、ビジネスはリアルタイムで脆弱性を検出することができます。本セクションでは、継続的な監視の利点、セキュリティメトリックとパフォーマンスの分析、および脆弱性管理プログラムを長期的に効果的にするための改善方法について探求します。

11. 脆弱性管理における自動化の役割

自動化は中小企業における脆弱性管理プラクティスを大幅に向上させることができます。本セクションでは、自動化の利点、脆弱性スキャンツールの自動化と効率的なインシデント対応の実施について詳しく説明します。

12. コンプライアンスと規制の考慮事項

業界固有の規制やデータ保護法に準拠することは中小企業にとって重要です。本セクションでは、業界固有の要件の理解、監査と評価の実施、適用される基準に準拠するための適切なセキュリティ対策の実装について説明します。

13. 予算とリソースの最適化

中小企業では予算とリソースが制約されているため、最適化が重要です。本セクションでは、リソースの最適化と予算割り当ての方法、セキュリティに対する投資の重要性、およびビジネス目標とセキュリティ目標の調整について説明します。

14. 継続的な教育と改善

脆弱性管理は常に進化しています。本セクションでは、継続的な教育とトレーニングの重要性、セキュリティに関する最新のトレンドと脅威に対する意識を高める方法について議論します。継続的な学習と改善により、ビジネスはセキュリティリスクに対して常にアンテナを張ることができます。

結論

中小企業における脆弱性管理のベストプラクティスは、ビジネスがセキュリティリスクを最小限に抑え、潜在的な被害を防ぐための重要な手法です。適切な脆弱性管理計画、リスク評価と優先順位付け、定期的なパッチ適用、ネットワークセキュリティ対策、社員のトレーニング、インシデント対応、サードパーティのリスク管理、継続的な監視と改善、自動化の活用、コンプライアンスと規制の遵守、予算とリソースの最適化、継続的な教育と改善などが重要な要素です。

よりセキュリティ意識の高い文化を育み、セキュリティリスクを常に監視することで、中小企業はサイバー攻撃に対するより堅牢な防御を確立することができます。
【MySQL】本番環境だと問題ないのにテスト環境だとロック取り合いになる時にチェックすること

割と沼にハマりがちな知見を得たのでメモ。

本番環境だと問題なく動いていたバッチに手を加えたのでテスト環境で動作チェックしたら、なぜかロック取り合いで落ちた。何回やり直してもだめ。
そんな時は**テストデータのレコード数が少ないことが原因**かもしれないです。

**レコード数に対して、相対的に多くの要素をIN句に指定するとフルスキャンになってしまうので注意。**

## 例

次のようなテーブルにて、IN句に16個のキーを指定してWhereで絞り込むとします。
```
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int unsigned | NO   | PRI | NULL    |       |
| value | int unsigned | NO   |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
```

### レコード数が60件のとき
```
mysql> select count(*) from lock_test;
+----------+
| count(*) |
+----------+
|       60 |
+----------+
```

レコード数が30件のテーブルに対して16個のIN句でWhereをかけるときちんとインデックスが効いている。
問題なし。
```
mysql> explain select * from lock_test where id in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
+----+-------------+-----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table     | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | lock_test | NULL       | range | PRIMARY       | PRIMARY | 4       | NULL |   16 |   100.00 | Using where |
+----+-------------+-----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
```

### テーブルサイズが30件のとき
```
mysql> select count(*) from lock_test;
+----------+
| count(*) |
+----------+
|       30 |
+----------+
```
対して、レコード数が30件のテーブルの場合。
```
mysql> explain select * from lock_test where id in (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | lock_test | NULL       | ALL  | PRIMARY       | NULL | NULL    | NULL |   30 |    53.33 | Using where |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
```

60件の時と同様、IN句に16個のキーを指定してWhereをかけたのですが、インデックスによる検索ではなくテーブルスキャンになってしまっています。


## ハマりがちなポイント

実はこれ実務でかなりハマりまして。
とある安定して動いているバッチがあるのですが、これに手を加えることになり、最小限のテストデータを用意して開発環境で回してみたわけですよ。

**そしたらバッチが落ちる落ちる。**

原因は`Lock wait timeout exceeded.`
ロックの取り合いになっていたわけです。

しかし本番では何万、何十万のレコードを処理しているにも関わらずロックの取り合いなんかにならず安定して動いているわけで、なぜ数百レコードのテスト環境だとロックの取り合いになる・・・？

丸一日潰して出た結論が、「テストデータの数が本番データに比べて圧倒的に少ないから」でした。
MySQLくんがご丁寧にチューニングしてくれた結果、「このレコード数に対してこの数のIN句ならばテーブル全部スキャンした方が早いよね」って判断してくれちゃったんですね。
そのおかげでテーブル全体にロックがかかり、他のトランザクションがロック待ちになると。

いい知見が得られました。
同じように「本番だと動いてたのにテストデータだとなぜかロック取り合いで落ちる」って人はこの点に注意してみると良いかもです。
2023/6/12主にITとかセキュリティの記事

Windowsの深刻な脆弱性、PoCが公開される - 注意を(6/10)
https://news.mynavi.jp/techplus/article/20230610-2700792/

「Qilin」「Agenda」「.MmXReVIxLV」ランサムウェア感染時の対処方法を解説(6/9)
https://cybersecurity-jp.com/column/83958

2023年にサイバー攻撃を受ける確率は何パーセント？(6/8)
https://kn.itmedia.co.jp/kn/articles/2306/08/news073.html

Microsoftが警告　ハッキング集団「Volt Typhoon」の手口と対処法(6/10)
https://atmarkit.itmedia.co.jp/ait/articles/2306/10/news051.html

トヨタ紡織、欧州子会社に不正アクセス　データ流出(6/10)
https://www.nikkei.com/article/DGXZQOFD101AX0Q3A610C2000000/

情報漏洩対策を事例から考えよう。対策方法を原因や損害とともに紹介
https://www.ntt.com/business/services/network/internet-connect/ocn-business/bocn/knowledge/archive_50.html

「うちのPC、遅すぎ？」と感じたら要注意　Windows 11のよくあるパフォーマンス問題を確認しよう(6/10)
https://news.yahoo.co.jp/articles/20d0372bbc0a28b0ba77c804c2dcbb930791b0fe?source=rss

情報漏洩の事例を教訓に。原因や企業に求められる対策のまとめ
https://www.ntt.com/business/services/network/internet-connect/ocn-business/bocn/knowledge/archive_48.html

ＵＳＢ紛失問題　尼崎市が業務委託先に損害賠償請求(6/10)
https://www.fnn.jp/articles/-/540699

電通国際情報サービスに不正アクセス、一般ユーザー権限でのデータ参照の形跡(6/9)
https://scan.netsecurity.ne.jp/article/2023/06/09/49494.html

成功のカギは「段階的」「対話」デンマークが“ナンバー制度”に成功した理由(6/9)
https://news.tv-asahi.co.jp/news_international/articles/000302804.html

米司法省、マウントゴックス事件の容疑者を特定・起訴(6/10)
https://coinpost.jp/?p=466887

「中共のネット検閲」に立ち向かい投獄された夫、その妻も外部との連絡を絶たれる＝中国(6/10)
https://www.epochtimes.jp/2023/06/155371.html

サイバーテロ対策確認　茨城県協議会　育樹祭、G7向け(6/10)
https://ibarakinews.jp/news/newsdetail.php?f_jun=16863124005808

デジタル人材育成のためのアドバイザー派遣と 社内研修サポートを希望する中小企業を募集します！(6/9)
https://www.pref.aichi.jp/press-release/digital-advisor-r5.html

愛知総合工科高校専攻科でデジタル人材の育成に向けたデータサイエンス講座(6/10)
https://news.yahoo.co.jp/articles/919379906bfc23ab4cf499f6ee23d88e58243111?source=rss
UnrealEngineにテクスチャを読み込んだとき色がおかしい

# はじめに
UnrealEngineにテクスチャを読み込んだとき、元の色と変わっていたためいろいろ調べてみました。
今回はSubstanceDesignerを使用したときのものになります。
はじめてQiitaを使用するため不備や見づらい等あればご連絡ください。


# 起きた問題
UnrealEngineに16bitテクスチャを読み込んだとき色が変わってしまいます。

![FuU7Gq4agAAGs6Y.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475959/53c689a2-b990-7461-4a2a-d6812cf324f4.jpeg)
拡大&比較
![jhgfds.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475959/b568e269-0555-af46-b537-4205c0cac79b.png)


***

**テクスチャ設定をいっじてみる**
テクスチャ設定の中にあるsRGBのチェックを外すとテクスチャ上の色は元に戻る
![FuU7njvaYAAeU7Y.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475959/eed3f621-d74f-980c-ca77-5fe1c36d02f4.jpeg)

しかし、マテリアル上には反映されてない。
sRGBのチェックを外すことでテクスチャ上の見た目は元に戻るが、マテリアルに持ってきたときに見た目がおかしいまま
![スクリーンショット 2023-06-12 021348.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475959/076f4f5f-0f09-8c89-cc43-3895dc1a7659.jpeg)


# 原因と解決策
**8bit と 32bit で出力した場合は問題が起きなかった。**(16bit出力がダメみたい。)
SubstanceDesignerはデフォルトで16bit出力になっているためこのようなことが多い。

![FuVG0afagAAsKnv.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475959/6f7bf781-1a62-8978-8c05-f310b6aea1c1.jpeg)


# SubstanceDesignerで 8bit 32bit 出力のやり方
### 8bit
8bit設定にしたlevelノードを挟む
![FuVHctDaAAAd5vY.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475959/709fbb63-7662-8a99-275a-be16acb02946.png)
または、
tgaファイルで出力（強制的に8bitになる）
![FuVHdM6akAAAZCd.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475959/a339dc54-4430-e948-4658-66f7a3fc8da8.jpeg)

### 32bit(24bit)
SubstanceDesignerのフォーマットを32bitにして、
![FuVHlOJagAIhAEi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475959/16b48afa-ea3a-58a0-2047-1172d9026a41.png)
psdデータで出力
![FuVHl7haEAEk7aC.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475959/ab71e176-d005-8d05-6322-ffccca17a2a9.jpeg)
photoshopの書き出し形式でアルファを含めるか含めないか設定して出力
（アルファを使ってないならデータ量を減らすために外した方が良い）
![FuVHoSxaUAIsanD.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475959/76fc80bb-ae56-50aa-bce0-aa9fac93a7b1.jpeg)

:::note info
SubstanceDesignerのフォーマットを32bitにして出力してもなぜか16bit出力になるため、Photoshopを一度挟んで32bit出力にしています。
:::

# おわりに
だれかの役に立てれば嬉しいです。ではまた(^_^)/~

参考にした記事
https://note.com/thesaurus/n/n69d691d784a0
【VSCode】デフォルトのシェルを変更する方法

## デフォルト

デフォルトではLinuxおよびMacOSの場合`SHELL`に代入されているシェルが起動します。  

VSCodeを終了させた後にターミナルで次のコマンドを実行して再度起動します。  

```terminal
SHELL=/bin/bash code .
```

ターミナルを起動するとBashが起動します。  

![スクリーンショット 2022-12-08 16.19.52のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/3ecc4312-4466-aeae-2839-b7ae1cfcde14.png)

```terminal
SHELL=/bin/zsh code .
```

ターミナルを起動するとZshが起動します。  

![スクリーンショット 2022-12-08 16.26.52のコピー2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/effe7cdf-7cd6-7a82-f60e-84dae5675256.png)

特に`SHELL`の値を指定しない場合にはログインシェルのフルパスが`SHELL`に代入されます。  

`SHELL`の値を確認するには`echo $SHELL`を実行します。  

```terminal
$ echo $SHELL
/bin/zsh
```

## 既定のシェルを変更する方法

`settings.json`に以下のように記述します。  

```settings.json
{
  "terminal.integrated.profiles.linux": {
    "zsh (login)": {
      "path": "zsh",
      "args": ["-l"]
    }
  },
  "terminal.integrated.defaultProfile.windows": "zsh (login)"
}
```

するとLinuxでターミナルを起動するとの`zsh`がログインシェルとして起動します。  

また下画像の箇所より選択することでも設定できます。  

![スクリーンショット 2022-12-08 22.39.51のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/8b469013-04a7-4a07-538a-2b994ce8224d.png)
【SQL】テーブル結合について（inner joinとouter join）

# はじめに
データベースからデータを取り出す際、複数のテーブルからデータを取り度すことも多いかと思います。
しかし、それぞれのテーブルから別々データを取り出して、実際に処理するときに合わせるようにすると、手間も時間もかかってしまいます。
そのため、複数のテーブルをまとめて、そこからデータを抽出するという手段を取ります。
これを「結合」と言います。

# 今回のテーブル

今回は以下のテーブルを例に、内部結合(inner join)と外部結合(outer join)について説明します。

**teamsテーブル**
|id|name|
|---|---|
|1|first|
|2|second|
|3|third|
|4|fourth|

**membersテーブル**
|id|name|team_id|
|---|---|---|
|1|hitomi|2|
|2|nibe|1|
|3|mikuni|4|
|4|yosoya|2|
|5|ikarugi|1|
|6|mutsuki|5|

# 内部結合(inner join)
内部結合は、それぞれのテーブルの指定したカラムの値が一致するものだけを結合します。
membersテーブルとteamsテーブルから、membersテーブルのteam_idと teamsテーブルのidが一致するデータを取り出して結合する場合、以下のように書きます。
```sample.sql
    SELECT * FROM members
INNER JOIN teams 
        ON members.team_id = teams.id;
```
このSQLリクエストにより、下の新しいテーブルができます。
|id|name|team_id|id|name|
|---|---|---|---|---|
|1|hitomi|2|2|second|
|2|nibe|1|1|first|
|3|mikuni|4|4|fourth|
|4|yosoya|2|2|second|
|5|ikarugi|1|1|first|

teamsテーブルのthirdは所属するメンバーがmembersテーブルにいないため含まれていません。また、membersテーブルのmutsukiも該当するチームがteamsテーブルにないため含まれていません。

「内部結合」では、一致する値を持たないデータはテーブルから除外されます。

# 外部結合(outer join)
外部結合は、片方のテーブルにしかないデータも取得します。
よく使うものとして「LEFT OUTER JOIN」と「RIGHT OUTER JOIN」があります。
#### LEFT OUTER JOIN
左側（SQL文でFROMの後）のテーブルを基に外部結合をします。
#### RIGHT OUTER JOIN
右側（SQL文でJOINの後）のテーブルを基に外部結合をします。

## LEFT OUTER JOIN
```sample.sql
         SELECT * FROM members
LEFT OUTER JOIN teams 
             ON members.team_id = teams.id;
```
結果は以下のようになります。
|id|name|team_id|id|name|
|---|---|---|---|---|
|1|hitomi|2|2|second|
|2|nibe|1|1|first|
|3|mikuni|4|4|fourth|
|4|yosoya|2|2|second|
|5|ikarugi|1|1|first|
|6|mutsuki|5|NULL|NULL|

membersテーブルのmutsukiも該当するチームのデータが「NULL」のまま含まれているのがわかります。

## RIGHT OUTER JOIN
```sample.sql
          SELECT * FROM members
RIGHT OUTER JOIN teams 
              ON members.team_id = teams.id;
```
結果は以下のようになります。
|id|name|team_id|id|name|
|---|---|---|---|---|
|1|hitomi|2|2|second|
|2|nibe|1|1|first|
|3|mikuni|4|4|fourth|
|4|yosoya|2|2|second|
|5|ikarugi|1|1|first|
|NULL|NULL|NULL|3|third|

今度はteamsテーブルのthirdが所属するメンバーが無い状態で含まれているのがわかります。
【PHP】エルビス演算子とSwitch-Case文を組み合わせたテクニック

## 導入
本記事では、エルビス演算子を活用したスマートな変数定義とSwitchCase文を組み合わせたを紹介します。

## コード
```
$variable = $a ?: '';

switch ($variable) {
  case 'option1':
    // option1に対する処理
    break;
  case 'option2':
    // option2に対する処理
    break;
  default:
    // デフォルトの処理
    break;
}
```
### 気に入っているポイント
- 可読性が高い。
- 変数定義時のエラー処理も、FALSEに入るため簡単。
- if文のネスト・多用を防ぐことができるためパフォーマンスの向上にも寄与。
変数定義後で、nullの場合で`return`すれば尚良しですね。


## 最後に
普段はDruaplを使ってのWeb開発をしております。
条件分岐・エラー処理の記述をどうにか簡略化しつつ、尚且つパフォーマンスの向上にも繋げれないかなと、模索して汎用的に使えそうなテクニックを見出せたので、今回備忘録として残させていただきました。
PHP歴8ヶ月ほどでお見苦しい部分もあるかと思いますが、「こうしたほうがいいよ」「こういう方法もあるよ」などあればご教授願います。
dockerエラー。no space left on device

```
failed to solve: rpc error: code = Unknown desc = failed to create .....png: no space left on device
```
と出た。
兎に角dockerのイメージやコンテナを削除。

途中
```
ERROR [mysql:5.7.35 internal] load metadata for docker.
```
と出た場合は
```
+++ b/dockerfiles/mysql/Dockerfile
@@ -1,4 +1,4 @@
-FROM mysql:5.7.35
+FROM --platform=linux/x86_64 mysql:5.7
```
 を追加(Mac M1だけ？？)。

結局
Disk image sizeを上げたらいけた
![スクリーンショット 2023-06-12 1.28.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270048/21f03021-fcb5-511e-f9b7-8ff687f714ad.png)
Xcodeでリダイレクト

`Xcode`で入出力ファイルの`リダイレクト`を行いたい場面に遭遇し，試行錯誤しているうちにできるようになったので，ここに手順を書き留めておきます．
どなたかのお役に立てれば幸いです．

## 1. 作業用ディレクトリと入出力ファイルの準備

今回は`/Users/ashipan/Redirection` のディレクトリ内に`main.cpp`, `input.txt`, `output.txt`ファイルがあるとして作業を進めていきます．
ディレクトリ構成やファイル名は自分の環境に合わせて読み替えて進んでください．
今回行いたい`リダイレクト`は以下のようなものです．(`a.out`は実行ファイル)
```
./a.out < input.txt > output.txt
```

## 2. Working Directory の設定

`Xcode`のメニューバーから `Product` > `Scheme` > `Edit Scheme` を選択します．左の`Run`と右の`Options`を選択して`Use custom working directory`を選択し, `working directory`に入出力ファイルがある場所(`Users/ashipan/Redirection`)を指定します．

![Screenshot 2023-06-12 at 0.07.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2379813/6ab3ec9c-4635-8e95-1936-ae5d67af44e8.png)

## 3. プログラムの実行

`input.txt`に入力される値，`main.cpp`にその入力から所望の出力を得るプログラムを書きプログラムを実行します．
`input.txt`から入力を得るには`main`関数の冒頭に以下の記述を行ってください．
```
freopen("input.txt", "r", stdin);
```
また，`output.txt`に出力したい場合は同様に以下の記述を行ってください．
```
freopen("output.txt", "w", stdout);
```
`macOS`でコンパイルを行う場合は以下のように書くこともできます．
```
#ifdef __APPLE__
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
```
以下に`input.txt`と`main.cpp`のサンプルプログラムを置いておきます．
```input.txt
3
1 2 3
```

```main.cpp
#include <bits/stdc++.h>
using namespace std;

int main()
{
  freopen("input.txt", "r", stdin);   // Input Redirection
  freopen("output.txt", "w", stdout); // Output Redirection

  /* if you are compiling on macOS, you can instead write as follows
  #ifdef __APPLE__
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
  #endif
  */
  
  // n個の整数を読み取りその合計を出力
  int n;
  cin >> n;
  vector<int> a(n);
  for (int i = 0; i < n; i++) cin >> a[i];
  cout << accumulate(a.begin(), a.end(), 0) << endl;
  return 0;
}

```

### 4. 実行結果の確認

プログラムの出力内容は`output.txt`に記録されます．
以下の`output.txt`は入力ファイルである`input.txt`に対して`main.cpp`を実行した結果です．
```output.txt
6
```

### 5. 終わりに
これで`Xcode`で`リダイレクト`ができるようになったと思います．
また，`main.cpp`内の`bits/stdc++.h`が気になった方はこちらの記事を参考にしてください．
[Xcodeでbits/stdc++.hをインクルード](https://qiita.com/Ashipan/items/6780eeb0d43c19ac9fe0)
Cloud9でOauth2を使用する方法

# 作業環境
* Laravel 9.52.7
* Cloud9

# 本文
基本的に@tomoaki052618さんの
https://qiita.com/tomoaki052618/items/98f93c090ae04cb50ffd
↑この記事を参考に実装できた．
*** 
GOOGLE_CALLBACK_URL=コールバックのURL
↑この部分を誤っていたために苦労した．

Cloud9のプレビューのURLは，
https://[ユーザ名]-[ワークスペースID].vfs.cloud9.[リージョン].amazonaws.com
のように構成される．

GOOGLE_CALLBACK_URL=https://[ユーザ名]-[ワークスペースID].vfs.cloud9.[リージョン].amazonaws.com/auth/google/callback

と設定する必要があった．
JUnitの並列実行が実行時間削減にどれだけ効果があるのかを検証する

# 前提

## 用意するテストケース
サンプルコードとしてよく用いられるFizzBuzzのコードを使用します。
今回は１つのテストクラスに４つのテストコードを準備しました。
また、実装コードには１秒のスリープを実装しており、１スレッドであれば４秒強かかるテストです。
同一の内容で複数のテストクラスを用意して、実行時間を計測します。

```java
    @Test
    public void 引数に15を与えたらFizzBuzzを返す() {
        FizzBuzz fizzbuzz = new FizzBuzz();
        assertEquals("FizzBuzz", fizzbuzz.response(15));
    }

    @Test
    public void 引数に3を与えたらFizzを返す() {
        FizzBuzz fizzbuzz = new FizzBuzz();
        assertEquals("Fizz", fizzbuzz.response(3));
    }

    @Test
    public void 引数に5を与えたらBuzzを返す() {
        FizzBuzz fizzbuzz = new FizzBuzz();
        assertEquals("Buzz", fizzbuzz.response(5));
    }

    @Test
    public void 引数に1を与えたら1を返す() {
        FizzBuzz fizzbuzz = new FizzBuzz();
        assertEquals("1", fizzbuzz.response(1));
    }
```

## 並列処理の設定方法（実行時スレッド数の設定）


```build.gradle
// 省略

test {
	useJUnitPlatform()
	maxParallelForks = 4 // ここに最大スレッド数を指定
}
```

# 検証結果

|最大スレッド数|実行クラス数|総テストケース数|実行時間|考察|
|---|---|---|---|---|
|1|1|4|約4秒||
|1|4|16|約16秒|単純計算で前ケース4倍となった|
|2|1|4|約4秒|同一クラスでは並列処理は実行できないため、1スレッドの場合と結果に変化無し|
|2|4|16|約8秒|2スレッドで4クラスを処理するため、実行時間が半分となった|
|4|1|4|<font color="red">約4秒|同一クラスでは並列処理は実行できないため、1スレッドの場合と結果に変化無し|
|4|4|16|<font color="red">約4秒|4スレッドで4クラスを処理するため、実行時間が1クラス分と同じになった|
|4|5|16|<font color="red">約4秒|4クラスのみの為、5スレッド目は有効とならず前ケースと同じ結果となった|

# 結論
* 同一クラスのテストは必ず同一スレッド上で実行されるため、並列処理されない
* 複数クラスのテストはスレッド数と実行時間が反比例の関係となった

# 注意点
* JUnitの実行レポートは全ての実行時間を足した結果であるため、実際の実行時間とは異なります。今回は、ビルド結果のログ情報に出力された時間を参考に計測しています。
* 今回は全てのテストクラスを同一の処理にしているため、スレッド数と実行時間が反比例の関係となりましたが、各テストクラスの規模により、効果は大きく変わってきます。
Compute EngineにローカルIPのみでアクセスする方法(編集者ロールだけだとだめだった)


# 結論
* Compute EngineにローカルIPのみ付与してSSH接続するには以下が必要
　1. Identity-Aware Proxy(IAP)機能を使う
　2. IAPで保護されたトンネル ユーザー（roles/iap.tunnelResourceAccessor）ロールが必要　★編集者ロールにはこのロールの権限がないことに注意

## やろうとしたこと、やったこと
セキュリティを考慮して、Compute Engine(VM)にはなるべくグローバルIPアドレスを付与せずにローカルIPアドレスのみ付与したい。
[Identity-Aware Proxy機能](https://cloud.google.com/iap?hl=ja)を利用してローカルIPアドレスのみで対象VMにコンソール画面からSSH接続しようとした。

しかし、個人用アカウントではうまくいったのだが、業務用のアカウントでは以下のメッセージが出て、ローカルIPアドレスのみでSSH接続ができなかった。(sshコマンドでIAP機能利用しようとしても失敗)
![スクリーンショット 2023-06-11 23.46.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3311265/80d874b8-8259-94b8-de59-ca358f920805.png)

## 原因
「IAPで保護されたトンネル ユーザー（roles/iap.tunnelResourceAccessor）」ロールが足りていなかった。

個人用アカウントは"オーナー"ロールだったのでほとんど全てのことができるロールであったが、業務用のアカウントは"編集者"アカウントが割り当てられていた。(お試し環境であったのだが、編集者ロールなら大体のことができるだろうという安易な考えであった。)

そのため「IAPで保護されたトンネル ユーザー」ロールを追加することで、IAPによるSSH接続ができるようになった。

【ロール設定参考】
(1)「IAMと管理」の「IAM」から、該当ユーザ(プリンシパル)の編集ボタン(赤枠)を押下
![スクリーンショット 2023-06-12 0.03.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3311265/9f496afb-6fb1-4ee3-448d-f655a08e843c.png)

(2)「別のロールを追加」を押下
![スクリーンショット 2023-06-12 0.05.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3311265/70ab502b-bf01-848d-ed1b-21f7a41583bb.png)

(3)「ロールを選択」を押下
![スクリーンショット 2023-06-12 0.07.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3311265/4b75427d-34eb-a598-48bd-a502f1e293a3.png)

(4)「IAP」等入力し、「IAPで保護されたトンネル ユーザー」ロールを検索
![スクリーンショット 2023-06-11 23.53.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3311265/a7674b87-f536-e99f-da37-efbbe89d7a4a.png)

(5)「IAPで保護されたトンネル ユーザー」ロールが追加されていることを確認
![スクリーンショット 2023-06-11 23.57.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3311265/925ff131-9f02-55df-b0d5-8a3a91ccfab0.png)

## 最後に(所感)
編集者ロールならなんでもできると思い込んでロール設定に行き着くまでに時間がかかってしまった。
また、普段からオーナーロールで操作しているとロールを意識しないで操作できるので、個人アカウントでもちゃんとロールを意識して付与しなおす必要があるなと思う。
SLAとSLOとSLI：サービス品質を評価するための鍵要素

Title: SLAとSLOとSLI：サービス品質を評価するための鍵要素

はじめに
サービス提供者にとって、信頼性と品質の維持はビジネスの成否に直結する重要な要素です。しかし、その評価基準や指標を明確にすることは容易ではありません。本記事では、サービス品質を評価するための鍵要素として、SLA（サービスレベル契約）、SLO（サービスレベル目標）、およびSLI（サービスレベル指標）について解説します。

1. SLA（サービスレベル契約）
SLAは、サービス提供者と顧客との間で合意される契約です。これは、サービスの品質や可用性、サポートレスポンス時間などの具体的な目標と責任を明確にします。SLAは、顧客とサービス提供者の双方にとって、期待値と現実の間のギャップを埋めるための枠組みとなります。

2. SLO（サービスレベル目標）
SLOは、SLAの一部として定義される具体的な目標です。SLOは、特定のサービスの品質やパフォーマンスに関する期待値を表します。例えば、サービスの可用性を99.9%に保つ、応答時間を200ミリ秒以下に維持するなどの具体的な目標がSLOとして設定されます。SLOは、サービス提供者がサービス品質を測定し、改善するための基準となります。

3. SLI（サービスレベル指標）
SLIは、サービスの品質やパフォーマンスを定量的に測定するための指標です。具体的な測定方法はサービスによって異なりますが、一般的な例としては、エラーレート、レスポンス時間、スループットなどがあります。SLIは、SLOの達成度を評価するための基礎となり、品質改善のためのデータ駆動型のアプローチを可能にします。

まとめ
SLA、SLO、およびSLIは、サービス品質の評価と改善において重要な要素です。SLAは、顧客とサービス提供者の間で契約と

して合意される目標と責任を明確にします。SLOは、具体的な目標を設定し、サービス品質の評価と改善の基準となります。SLIは、定量的な測定指標を提供し、SLOの達成度を評価するための基礎となります。

この記事は、サービス品質の評価において重要な概念であるSLA、SLO、およびSLIについて解説しました。詳細な情報や実際の事例については、以下のリンク先の記事を参照してください。

[SLA vs. SLO vs. SLI](https://last9.io/blog/sla-vs-slo-vs-sli/)

これらの概念を理解し、適切に活用することで、サービス品質の向上と顧客満足度の向上に貢献できるでしょう。
ネコを呼び出すコマンド😺『neko』


ネコを呼び出すコマンド😺『neko』を作成しました。
https://github.com/RyotaroSeto/neko
![](https://storage.googleapis.com/zenn-user-upload/660efd370540-20230611.png)


## インストール
Homebrewのコマンドでインストールできます。
```
$ brew install RyotaroSeto/tap/neko
```
最新のversionに更新する場合は`upgrade`を使用してください。
```
$ brew upgrade RyotaroSeto/tap/neko
```

## 使い方
サブコマンドの`name`をつけることで自動的にネコの名前を命名してくれます。
```
$ neko name
```
![](https://storage.googleapis.com/zenn-user-upload/554dd9e7d05d-20230611.png)

自動的に名前を命名してくれましたね！今回は`Kawabata`さんです。

では`Kawabata`さんを呼んでみましょう！
```
$ neko Kawabata
```
![](https://storage.googleapis.com/zenn-user-upload/0ba123233157-20230611.png)
`Kawabata`ネコさんが出力されました。名前を標準入力で呼んであげると...
![](https://storage.googleapis.com/zenn-user-upload/21ebbdc8b76c-20230611.png)
![](https://storage.googleapis.com/zenn-user-upload/064889ef711d-20230611.png)

`Kawabata`ネコさんが標準出力で返事をしてくれました😺

もちろん引き続き更新していくので`version`の確認もできます。
```
$ neko -v
```
![](https://storage.googleapis.com/zenn-user-upload/39da09609b24-20230611.png)

今回のコマンドは[cobra](https://github.com/spf13/cobra)を使用したため、簡単にCLIをすることができました！
RTX4070→RTX3060にダウングレード時にハマって諦めたこと

Ubuntu22.04でRTX4070→RTX3060にダウングレード時にハマって諦めたことを書きます
結論はOSを入れ直しました

# 前提事項
・RTX4070を実装していて、nvidiaの公式ページからドライバーをダウンロードしてインストールした（2023/6/11時点）
・ドライバーを消してRTX3060に差し替える

# 現象
・起動してXが立ち上がった後文字が読めないくらい黄色い画面になる

# 予想
・完全にカーネルをドライバーインストール前に戻せたら対処できたかも…
　└カーネル指定して起動時はなぜか正しくXが起動できる

今回は時間がなかったためにOSを入れ直す決断をしました（解決するより入れ直したほうが早いから）
PythonのWikipediaライブラリPageメソッドで目的のページが出てこない時に試すこと

Wikipediaのスクレイピングをする際、MediaWiki APIを使う人が多いでしょうが、Python使いの中には、[wikipedia](https://github.com/goldsmith/Wikipedia)ライブラリを使う人もいらっしゃるのでないでしょうか？

私も使っています。

https://qiita.com/muto-jo/items/79c41aa2fb8ff27c047c

さて、上の記事で108期生（2022年度入団）までの宝塚の生徒一覧のデータを作ってまして、最近、109期生(2023年度入団)の一覧を作ろうとした時にハマった点を共有します。

# すでにあるページなのに.page()で取れないならauto_suggest=Falseを試す

この記事の結論です。

そのページがあるのが確実なのに、`wikipedia.page("title")` を使って、違うページが取れてしまう場合、auto_suggestをFalseにしてみましょう。

```Python
import wikipedia
page_data = wikipedia.page('title', auto_suggest=False)
```

## 解説

説明のためwikipediaライブラリの本体であるwikipedia.pyでpage()の一部を引用します。

```Python
  if title is not None:
    if auto_suggest:
      results, suggestion = search(title, results=1, suggestion=True)
      try:
        title = suggestion or results[0]
      except IndexError:
        # if there is no suggestion or search results, the page doesn't exist
        raise PageError(title)
    return WikipediaPage(title, redirect=redirect, preload=preload)
```

※引用し忘れましたが、auto_suggestは未指定時はTrueです。

ご覧の通り、auto_suggest=Trueの場合、page()はまずタイトルで検索をし、その結果をもとにページ内容を取得するようになっています。

ページタイトルが実在するにも関わらず、searchの結果に指定したページタイトルが存在しないと、searchで引っかかった別ページの情報が取れてしまうんですね。

それを防ぐには、auto_suggest=Falseを指定して、search()しないようにしましょう。

# 具体例（私のはまった事例）

私の取りたかったページはこちらです。  

https://ja.wikipedia.org/wiki/%E5%AE%9D%E5%A1%9A%E6%AD%8C%E5%8A%87%E5%9B%A3109%E6%9C%9F%E7%94%9F

```Python
import wikipedia
wikipedia.set_lang('ja')
page_data = wikipedia.page('宝塚歌劇団109期生')
```

とすると、取れるページのURLはこちらになります。

https://ja.wikipedia.org/wiki/%E5%AE%9D%E5%A1%9A%E6%AD%8C%E5%8A%87%E5%9B%A3

wikipedia.search()をしてみると下記が出てきます。

```Python
l = wikipedia.search('宝塚歌劇団109期生')
print(l)
['宝塚歌劇団', '宝塚歌劇団7・8期生', '宝塚歌劇団83期生', '宝塚歌劇団40期生', '宝塚歌劇団96期生', '宝塚歌劇団95期生', '宝塚歌劇団31期生', '宝塚歌劇団33期生', '宝塚歌劇団89期生', '宝塚歌劇団32期生']
```

先頭、l[0]が"宝塚歌劇団"そのもののページですね。これのページ内容が取得されてしまっています。

面倒なのでソースは端折りますが、auto_suggest=Falseを指定すると、取得したかった109期生のページが取得できます。

wikipediaライブラリは、MediaWiki APIのqueryアクションを使っているので、それの結果がそうなっているんでしょうね(未確認)。

# 他の解決方法

wikipedia.page()はページタイトルのほか、page_idを指定することもできます。  
page_idでの取得はsearch()を通さないので、page_idがわかっているなら、それを指定するのも手です。

これは試してないのでサンプルソースは省略します。
ubuntu(virtual box)にpython開発環境を構築してみた

参照サイト
https://invisiblepotato.com/ubuntu01/
https://self-development.info/ubuntu%E3%81%AB%E6%9C%80%E6%96%B0%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%AEpython%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B/
https://www.python.jp/install/ubuntu/index.html
https://www.digitalocean.com/community/tutorials/how-to-install-git-on-ubuntu-22-04


# Pythonをインストールする
## ビルドツール・ライブラリのインストールする
```shell
$ sudo apt update
$ sudo apt install build-essential libbz2-dev libdb-dev \
  libreadline-dev libffi-dev libgdbm-dev liblzma-dev \
  libncursesw5-dev libsqlite3-dev libssl-dev \
  zlib1g-dev uuid-dev tk-dev
```

## ソースコードをダウンロードする
https://www.python.org/

<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/2202b4c1-8338-8e57-18ed-f839bdd87f33.png">

## ソースコードの展開・ビルドする
```shell
tar xJf Python-3.x.y.tar.xz
cd Python3.x.y
./configure --prefix=/home/user/.local/python
make
make install
```
--prefixを指定しないと/usr/local/にインストールされる



# VSCodeをインストールする
https://code.visualstudio.com/Download

## debをダウンロードする
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/fc788ebc-519a-a847-5012-9e52f4fa18ad.png">

## debをインストールする
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/b4097d3c-73de-3585-db5b-a6cbf45f1563.png">
<br>
<img width="200" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/572e6a4f-e566-c5c4-9615-5f5d260e406d.png">

debをインストール完了した
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/a6e031d4-8013-02d6-ebab-f78f443beaf6.png">


# VSCodeを設定する

## 日本語化する
初回起動時に日本語環境をインストールするか訊かれるのでインストールする
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/c07b1658-8e9f-cb43-ff85-64a823ed365d.png">

## VSCode用Python拡張機能をインストールする
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/8e5d725a-b507-be48-1346-235a8ba7730f.png">

## コンパイラを指定する
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/503ce4a5-c925-0dfb-a709-f34072969923.png">

/home/user/.local/python/bin/Python3.x

# pythonを実行する
## helloWorld.pyを生成
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/bf417dbe-de75-c705-bc72-d16922d7d7c2.png">

## コードを書く
```python:helloWorld.py
print("Hello World")
```

## 実行する
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/384f12d3-6e96-f3ee-8141-308111c05ccf.png">

無事HelloWorld!が表示された
【Android】アプリから他SNSシェアをする【Kotlin】

# はじめに
androidアプリ内でSNSに画像やURLなどをシェアする方法を学んだので、今後のために記事にしてやり方を残しておこうと思います。

# 端末のシェア機能
    val shareIntent: Intent = Intent().apply {
        action = Intent.ACTION_SEND
        putExtra(Intent.EXTRA_TEXT, text)
        type = "text/plain"
    }
    startActivity(Intent.createChooser(shareIntent, ""))

# Twitter
```
val text = URLEncoder.encode("投稿したいテキスト", "UTF-8");
val uri = Uri.parse("twitter://post?message=$text")
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)
```

テキストに　"$hashTag"を加えると　ハッシュタグをつけることもできる
# LINE
```
val text = URLEncoder.encode("投稿したいテキスト", "UTF-8");
val uri = Uri.parse("https://line.me/R/share?text=$text")
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)
```
# Instagram
```
startActivity(Intent("com.instagram.share.ADD_TO_STORY").apply {
    this.setDataAndType(投稿したい画像のURI, "image/*")
    this.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    this.setPackage("com.instagram.android")
})
```
# Facebook
```
val uri = Uri.parse("https://www.facebook.com/sharer/sharer.php?u=<URL>")
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)
```


# それぞれ端末内のアプリを開きたい場合

```
val uri = Uri.parse(getString(各アプリのURL))
CustomTabsIntent.Builder().also { builder ->
    builder.setShowTitle(true)
    builder.build().also {
        it.launchUrl(requireContext(), uri)
    }
        }
```

# 参考

https://developer.android.com/training/sharing/send?hl=ja#send-binary-content

https://qiita.com/Seo-4d696b75/items/c551540d4c706e283eb4


https://11-30am.com/38/?utm_source=qiita&utm_content=article
ProArt Z790-CREATOR WIFIでハマったこと

ProArt Z790-CREATOR WIFIを使ってますが、2023/6/11時点では比較的新しいのでUbuntuを動かすにハマりました

# 物理的にハマったこと
・メモリはDDR5-4800を使ってますが、4枚使う場合は4800MHzではメモリーテストでエラーが多発する
　└対処方法：BIOSで4000MHzに落とす

・Bluetoothのデバイス認識が怪しかった
　└理由はわからないが、付属のWifi用アンテナをつけると調子がよくなる
　└Ubuntu22.04はドライバー的に大丈夫そう

・Realforceが認識しない
　└対処方法：USB 2.0ハブを使うと認識できる

# ProArt Z790-CREATOR WIFIのオンボードデバイスでUbuntu22.04で認識が確認できたもの
  ・Wifi
  ・2.5G Lan
  ・10G　Lan
  ・USB 3.2（Thunderbolt 4は未検証）

# ProArt Z790-CREATOR WIFIのオンボードデバイスでUbuntu22.04で認識が確認できなかったもの
 ・オンボードオーディオデバイス
　　└デバイスドライバーが公開？されてるぽいけどカーネルのバージョンと合わず諦めた
　・電源管理
　　└電源OFFはできるが、カーネルがエラーメッセージを出しているが放置
Promiseとasync,await

# Promise
```
setTimeout(() => {
    console.log(1)
    setTimeout(() => {
        console.log(2)
        setTimeout(() => {
            console.log(3)
        }, 1000)
    }, 1000)
}, 1000)
```
setTimeoutのような非同期処理を同期的に処理させようとするとコールバック地獄となる。ネストが多重となり可読性が落ちる。

そこでPromise！！
```
const promise = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
        }, 1000)
    }
    )
}
promise().then(() => {
    console.log(1)
    return promise()
}).then(() => {
    console.log(2)
    return promise()
}).then(() => {
    console.log(3)
})
```
Promiseオブジェクトに非同期処理をまとめる。もしその非同期処理が正常に終了したならreslove関数をコールバックし、エラーが起こるとreject関数をコールバックする。

resolve,rejectは成功失敗を通知する関数。

成功した場合はthenで失敗した場合はcatchで後続処理を書く。

# async,await
もっと簡単にかけるのがasync,await
```
const promise = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
        }, 1000)
    }
    )
}
async function asyncFunc() {
    await promise()
    console.log(1)
    await promise()
    console.log(2)
    await promise()
    console.log(3)
}
asyncFunc()
```
大分スマートに書けるようになった。

asyncを関数につけると、その関数はreturnでPromiseのresolve()を返し、throwでPromiseのreject()を返す。

awaitをつけた関数は、Promiseが返ってくるまで処理を待つ。
非同期処理②

# 前回
https://qiita.com/pappy/items/7f8d5fcc5559d687fe98
# コールスタックとキュー
コールスタックは後入れ先出しの箱。後に入れれば入れるほど先に処理される。

同期的な考え方である。

しかし、setTimeoutのような非同期処理が入るとコールスタックとは別にキューが必要になる。

同期処理も非同期処理もまずは、コールスタックに積まれていく。

同期処理はそのまま処理されてコールスタックから抜けていくのだが、

非同期処理に渡された関数（コールバック関数）はコールスタック内で処理されずに

条件が満たされるまで隔離される。

そのあと、条件を満たしたらコールバックキューと言われるところにコールバック関数は移される。コールバックキューは先入れ先出しで、コールスタックが空になるまで待機する。スタックが空くと、入れる。これはイベントループによるものでコールスタックが空の場合、タスクキュー内のタスクをコールスタックへ取り出す。

では先ほどの例1の処理だと、

①１が出力（コールスタックで処理）

②setTimeout実行（コールスタックで処理後funcAを隔離）

③4出力（コールスタックで処理）

④(funcAは条件を満たすまで待機)1秒後funcAが実行(キューの中でスタックが空くのを待つ)→(スタックが空く)funcAが実行

⑤textが実行→funcBが実行（コールスタックで処理）

⑤2が出力（コールスタックで処理）

⑥funcB終了→funcAの続きを実行（コールスタックは後入れ先出し）

⑦3が出力（コールスタックで処理）

Promiseやasync,awaitはそんな非同期処理が入るとコードの可読性が落ちるのを防ぐために作られた。

https://qiita.com/sho_U/items/ff82aa576837198097ce

https://engineering.mercari.com/blog/entry/20220128-3a0922eaa4/
非同期処理

# 非同期とは
コールバック関数が代表される処理。

例１
```
function funcA(text) {
    text(); // funcBの処理
    console.log('3'); // funcAの処理
}

// コールバック関数 → funcAの呼び出し時に引数に指定される
function funcB() {
    console.log('2');
}

//実行
console.log('1');
setTimeout(() => {
    funcA(funcB);
}, 1000);
console.log('4');
```
これは1,4,2,3で出力。

例２
```
function funcA(text) {
    setTimeout(() => text(), 1000)
    console.log('3'); 
}
function funcB() {console.log('2');}

console.log('1');
setTimeout(() => {
    funcA(funcB);
}, 1000);
console.log('4');
```
これは1,4,3,2で出力。

同期処理は上から順番に実行されること。頭の中では、

(例1は

①１が出力

②setTimeout実行→1秒後funcAが実行

③funcAが実行

④textが実行→funcBが実行

⑤2が出力

⑥funcB終了→funcAの続きを実行

⑦3が出力

⑧funcA終了→ルートの実行に戻る

⑨4出力)

と思ってしまう。

例1,2も同期処理で実行コードの順番に実行されたら通常1→4できれいに並ぶはず、、、

実際、setTimeoutを抜くと1→4にきれいに並ぶ。

setTimeoutが悪い。setTimeoutなんか本番で使わないんじゃない？

しかし、本番のサイトとかではapiからgetしたりdbにconnectするのにわずかだが時間がかかる。

それを疑似的に作った場合setTimeoutが丁度いい。

どのように処理されているのか？

例1は

①１が出力

②setTimeout実行

③4出力

④1秒後funcAが実行→funcAが実行

⑤textが実行→funcBが実行

⑤2が出力

⑥funcB終了→funcAの続きを実行

⑦3が出力
プロセスとスレッド諸々

# プロセスとスレッドって何？

まずタスクってよく言う。マルチタスクとか（音楽聞きながら勉強する）

それと同じで、ググりながらパワポ作ったりすると2つのタスクが同時進行している。

1個のタスクが１個のプロセスを生み出す。タスク＝プロセスとして考える。

1タスク（1プロセス）の中に処理しないといけないことを細かく分解していったものがスレッド。

例えば現実で漢字勉強というタスクがあれば、それを処理に分けると

漢字勉強(タスク,プロセス)

- ひらがなを理解する(スレッド1)
- 漢字の意味を理解する(スレッド2)
- 漢字の書き方を理解する(スレッド3)

みたいな感じ。

それがOSからみたら色々なアプリに対してもあるってこと。

プロセスがメモリを確保しスレッド達がCPUにあれして、これしてと言う。

CPUのスペックをみると8コア16スレッドみたいに書かれているのもこれのこと。

1コアのなかでマルチスレッドの処理ができるのが現在当たり前。
# 並行処理と並列処理

並列、並行、ほぼ同じことを言ってるようで全然違う。日本語ってむずい。

簡単に言うと、並列がマジの同時処理。並行が偽りの同時処理。
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2082391/629f4feb-8066-6d36-359a-95a2334640c3.png)

スレッドがCPUコアに処理を頼む。その際、CPUのコア数に応じて並列で処理できる数が異なる。

コア数が多いCPUが高性能のため値段が高い。

マルチコアの処理は、マジの同時処理。

コア1~4で処理(スレッド)が同時に並列に処理されている。
スレッドにも処理するのにかかる時間はバラバラ。すぐ終わるものからめっちゃ時間食うものまで。

じゃあ、コア2に最初に入った処理がめちゃくちゃ時間かかるやつだったら、それまでコア2はその処理でずっと使われるのか？

それとも適度にスレッドを切り替えながら満遍なく処理を行うのか？

普段PCではスレッドを切り替えながら満遍なく処理を行っている。

これを並行処理。実際は同時に処理はされていないのだけど、処理スピードが異常なので普段PCを触っていて同時に処理されているように感じる。だけど実際は1コアの中で複数のスレッドを切り替え処理を行っている。
![Untitledｓ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2082391/aa829585-e6f5-36bb-39fd-c874d43c6118.png)

# 同期処理と非同期処理

同期処理はプログラムを上から順番に実行していく。

対して非同期処理は上から順番に実行されるとは限らない。

# 参考
https://resanaplaza.com/%E3%80%90%E7%B0%A1%E5%8D%98%E8%A7%A3%E8%AA%AC%E3%80%91%E4%B8%80%E7%9B%AE%E3%81%A7%E5%88%86%E3%81%8B%E3%82%8B%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%80%81%E3%82%BF%E3%82%B9%E3%82%AF%E3%80%81%E3%82%B9/