OmniAICreator/Qiita-1.07M huggingface dataset:
データベースシステムを不正に操作する攻撃（SQLインジェクション）

```
前提
プログラミング初学者(2~3ヶ月)が学んだ内容です。
実際の現場で通用しないことや間違った内容が含まれている可能性があります。
間違っている部分や浅い部分については追記やご指摘いただけると幸いです。
```
#データベースシステムを不正に操作する攻撃（SQLインジェクション)
アプリケーションの不備を利用して、データベースシステムを不正に操作されることがあります。
このような攻撃方法をSQLインジェクションといいます。
SQLインジェクションの前にSQLとは何かについて先に解説します。
##SQLとは？
SQLはStructured Query Languageの略でデータベース言語です。
データベース言語とはデータベースとやり取りする時に使われる言語です。
例えば、
日本人に話すときは日本語を、ドイツ人に話すときはドイツ語をといったように、
データベースに何らかの処理をしてほしいときはデータベース語つまりSQLを使って指示して下さい。
ということです。
具体的な処理としては、データベースにデータを挿入したり、検索したりする時に使われます。
数万、数百万以上のデータであっても、SQLを使うことで効率的に作業することが可能になります。
##SQLインジェクションとは？
「Webページのテキスト入力欄」や「URL」などにSQL文の断片を埋め込むことで、データベースを改ざんしたり、不正に情報を入手する手法
入力フォームから送信した値によって、アプリケーションが本来想定しないSQL文を実行させ、攻撃を行います。
例えば、フォームを送信する時に文章の中にユーザーの権限を変更するようなSQL文を仕込んで送信します。
すると、サーバーサイドでそのSQL文が実行され、ユーザー権限が変更されてしまうような処理が行われます。
Twitterでいうとツイートのフォーム部分にSQL文の断片を入力してデータベース上にある全てのツイートを情報を削除するといったようなことをすることです。（もちろんTwitterはきちんと対策がされています。）
###SQLインジェクションの対策
上記のようなSQLインジェクションの脆弱性を防ぐために、
SQL文が実行される際のプログラムの処理の流れを利用して、SQL文が変更されることを防ぐ方法が２つあります。
**対策①意味のある特殊文字のエスケープ
SQLにおいて意味を持つ特殊文字のエスケープによって対策できます。
SQL文中では「'」が文字列の終端を意味します。
例えば、ユーザーIDとパスワードを入力して一致するとログインできる機能を考えてみます。

```ruby
ログイン認証のSQLを以下とします。
SELECT * FROM users WHERE user_id='$uid' AND password='$pwd'

ここにログインのために以下のようなユーザーとパスワードを入力します。
$uid nako
$pwd ' OR 'A'='A

するとSQL文が以下のようになります。
SELECT * FROM users WHERE user_id='nako' AND password='' OR 'A'='A'

```
元々はusersテーブルのuser_idとpasswordが一致した時にログインするという記述でした。
しかし記述内容を見てみると、

```
password='' OR 'A'='A'
```
となっており、```password=''```か```'A'='A'```のどちらかが成立すればTrue、つまりログインできてしまうということになります。
もちろん'A'='A'はTrueなので、passwordがわかっていなくてもuser_idがnakoということさえ分かっていれば、アカウントにログインができてしまうということです。
細かく記述を見ていくと、ORの前の「'」の記述の終端を示しています。
その後のORから先が新たな記述となり、'A'='A'という記述になっています。
この場合、「'」のようなSQLにおいて意味を持つ特殊文字をエスケープすることで対策が可能です。

＊＊対策②より厳格なSQL文の生成**
ユーザーからの値をSQLへ反映する前に、SQL文の構造を確定する仕組みをとることで、より厳格に対策できます。
SQL文確定後にユーザーからの値を入れて実行するため、ユーザーの入力値によってSQL分が変更されることはありません。
この実装にはプレースホルダという記述が使われます。
**プレースホルダ**
プレースホルダはユーザーの値が入力されるまでの一時的な仮引数のようなもの
予め確定したSQLにおいて、可変の値が入力される箇所に配置します。
プレースホルダを使って指定しておくと、その部分は値として処理されます。
不正な値が入力されても、SQL命令に関わるような特殊文字は無効化され、SQLとして実行されなくなります。
##まとめ
SQLとはデータベースと遣り取りをする時に使われる言語のこと
SQLインジェクションはSQLをフォーム欄やURLなどに埋め込むことでデータベースの改ざん(変更・削除）を行う行為。SQLインジェクションの対策は
①SQLで意味のある特殊文字のエスケープ
②プレースホルダを用いて入力されるものを全て値に限定し、SQL文の構造を確定することで、SQL命令にかかわる特殊文字を無効化できる。

参考
https://blog.senseshare.jp/placeholder.html
【Laravel】Collectionのfilterメソッド

##はじめに
コレクションから指定した条件に当てはまるカラムのみ取り出したいなと思った時はありませんか。
そんな時はCollectionのfilterメソッドを使うと便利です。

##filterメソッドを使ってみる

filterは関数を使ってフィルタの是非を判定します。
filterメソッドは指定したコールバックでコレクションをフィルタリングします。
trueを返したアイテムだけが残ります。

```php
$collection = collect([1, 2, 3, 4, 5]);

$filtered = $collection->filter(function ($value, $key) {
    return $value > 3 && $value < 2;
});

$filtered->all();

// [1, 4, 5]
```

##終わりに
LaravelのCollectionのメソッドは他にも便利なものがたくさんあるので引き出しを増やしていくといいかもしれません。

参考：[コレクション 8.x Laravel](https://readouble.com/laravel/8.x/ja/collections.html#method-filter)
関係演算ー射影

応用情報技術者平成29年秋期 午前28


関係R(ID，A，B，C)のA，Cへの射影の結果とSQL文で求めた結果が同じになるように，aに入れるべき字句はどれか。ここで，関係Rを表Tで実現し，表Tに各行を格納したものを次に示す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/850bcd89-a9b7-1255-58da-9c241448417c.png)


１、射影は、
関係演算の1つで表の中から特定の列だけを取り出す操作です。

SQLでは1つの表に同じ内容が2回以上出現することを許容しますが、
数学の集合論に基づく関係モデルでは要素の重複が許されません。
すなわち厳格に言えば、射影は「
　・列の取り出し→
　・重複の排除」
を組み合わせた操作だということになります。

つまり、射影は、SQLのDISTINCTと同じですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/bf65edcc-e2e0-f824-6a8f-5e07be06c6d5.png)


参照：
https://www.ap-siken.com/kakomon/29_aki/q28.html
ストアドプロシージャの利点

応用情報技術者平成29年秋期 午前26

ストアドプロシージャの利点はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/c4418777-4f90-2f95-1f46-0b49eb243471.png)


１、ストアドプロシージャ(stored procedure)は、
データベースに対する一連の処理をまとめた手続きにして、データベース管理システムに保存したものです。利用者は通常のクエリを発行する代わりに、データベース管理システム内の手続きを呼び出すことによって目的の処理を実行させることができます。
クライアントからサーバに対してのストアドプロシージャ1回の要求で、データベースに複数のクエリを発行することができるので、クライアントから直に同数のクエリを発行する場合と比較して、クライアント－サーバ間のネットワーク負荷の軽減が期待できます。

２、実行計画とは、
SQLがDBで実行される手順を示します。

Oracleの場合、実行計画は、Oracleの内部コンポーネントであるコストベースオプティマイザ(CBO; Cost-Based Optimizer)が作成します。

３、バッファ/キャッシュとは
バッファはユーザとストレージとの間に割って入ることでSQL文のディスクアクセスを減らす。
キャッシュもユーザとストレージの中間に位置することで、データの転送遅延を緩和する。


参照：
実行計画
https://cosol.jp/techdb/2020/04/how_to_read_oracle_sql_execution_plan/

DBMSのメモリについて学習したことまとめ
https://qiita.com/oseibo/items/2a1ecb3524645f38444b

https://www.ap-siken.com/kakomon/29_aki/q26.html
Lenovo Chromebook Duet にオフィシャルの VS Code Insider をインストールする



# 準備
```sh
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install libnss3 libxkbfile1 libsecret-1-0 libnspr4 libsecret-common xsel
```

# VS Code Insiderをインストールする

Produce official ARM and ARM64 builds #106289
https://github.com/microsoft/vscode/pull/106289#issuecomment-691076575

上記のARM64のdebパッケージをダウンロードしてインストールする。

```sh
$ wget https://update.code.visualstudio.com/latest/linux-deb-arm64/insider
$ sudo dpkg -i insider
```

# 起動してみる
```sh
$ code-insider
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733/5c15873c-9cc8-1717-0ac9-9c255eea9200.png)
Rails6でtypescriptを使う

[docker-composeでRails6開発環境](https://qiita.com/lumbermill/items/873f5bf22d091b828c45)の手順に従って、Rails6の新しいプロジェクトが立ち上がった状態を想定しています。まずは、以下のコマンドでtypescriptをインストールします。

```bash
docker-compose exec web rails webpacker:install:typescript
```

最後に以下のようなメッセージが出ていればOKです。

```
info All dependencies
├─ ts-loader@8.0.3
└─ typescript@4.0.2
Done in 99.53s.
Webpacker now supports typescript 🎉
```

サンプルのファイルが`app/javascript/packs`に置かれています。
ここにTypeScriptを記述することができます。

```typescript:app/javascript/packs/hello_typescript.ts
// Run this example by adding <%= javascript_pack_tag 'hello_typescript' %> to the head of your layout file,
// like app/views/layouts/application.html.erb.

console.log('Hello world from typescript');
```

コメント欄に書いてあるように、レイアウト(erb)の方にタグを追加します。

```erb:app/views/layouts/application.html.erb
<%= javascript_pack_tag 'hello_typescript' %>
```

railsのWebサーバを立ち上げた状態で、なにか適当なページにアクセスすると、webpackerが動き出して、jsファイルを生成してくれていることが確認できます。

```
web_1  | [Webpacker] Compiling...
web_1  | [Webpacker] Compiled all packs in /railsapp/public/packs
:
web_1  |     js/hello_typescript-a311f1059a83d1e0c165.js   4.12 KiB  hello_typescript  [emitted] [immutable]  hello_typescript
web_1  | js/hello_typescript-a311f1059a83d1e0c165.js.map   3.81 KiB  hello_typescript  [emitted] [dev]        hello_typescript
```

ブラウザのコンソールに「Hello world」が確認出来たらOK！

![Screen Shot 2020-09-12 at 8.22.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50780/bd7a8066-aa79-8124-619a-be12f1578986.png)
SVG(Scalable Vector Graphics)、OpenGL、PNG、TIFF

応用情報技術者平成29年秋期 午前25

W3Cで仕様が定義され，矩形や円，直線，文字列などの図形オブジェクトをXML形式で記述し，Webページでの図形描画にも使うことができる画像フォーマットはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/9e7a9cb2-1968-99e7-23fa-e073902da2cd.png)


１、SVG(Scalable Vector Graphics)は、ベクター形式の画像やイメージ，テキストなどの2次元CGをXMLで表現するための規格です。
・画像ファイルと異なりテキスト形式で記述するため、
・作成に専用のアプリケーションを必要とすることもありません。
・またJavascriptなどで記述内容を容易に操作することができるためWebページとの親和性が高く、
・インラインSVGをサポートするHTML5の普及に伴い今後の活用が期待されます。

※computer graphics、略称: CG

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/568f382e-2a8d-d209-10bc-aa7db953c99a.png)


２、OpenGL
Open Graphics Libraryの略。Linux、FreeBSDなどのPC UNIXに加え、Windows、Mac OS X等クロスプラットフォームで使用できる2D，3DCGを扱うためのAPIです。

３、PNG
Portable Network Graphicsの略。圧縮による画質の劣化のない可逆圧縮の画像ファイルフォーマットで、GIFよりも圧縮率が高く、現在ではほぼすべてのブラウザでサポートされているためWebページの画像フォーマットとして使用されます。

４、TIFF
Tagged Image File Formatの略。画像データを解像度・色数・カラーモデルなどが異なる複数の形式で1つのファイルに格納できるファイル形式です。


参照：
https://www.ap-siken.com/kakomon/29_aki/q25.html
重要な処理（購入処理）における脆弱性と対策(CSRF）

```
前提
プログラミング初学者(2~3ヶ月)が学んだ内容です。
実際の現場で通用しないことや間違ったことが含まれている可能性があります。
間違っている部分や理解が浅いと思われる部分についてはご指摘や追記いただければ幸いです。
```

重要な処理に対する攻撃の１つ、CSRF（クロスサイトリクエストフォージェリ）についてまとめました。
重要な処理とは例えば、
掲示板への投稿や、メールの送信、ECサイトでの商品購入といった本来外部から実行されてはいけない処理のことです。
CSRFではこの重要な処理を攻撃者が正規利用者になりすまして使う（リクエストを送る）ことを言います。
#CSRFの仕組みと対策
**具体的にCSRFはどのようなことをされるのか**
Webアプリケーションには以下のような重要な処理が存在します。
・クレジットカードでの決済
・メールの送信
・パスワードの変更
こういった重要な処理を正規利用者になりすまして攻撃者が使えてしまいます。
##CSRF(クロスサイトリクエストフォージェリ)
攻撃者がユーザーのログイン情報を盗み出し（セッションハイジャック）脆弱性のあるWebアプリケーションに対して、正規利用者になりすましてリクエストを送る攻撃のこと
なりすましのリクエストは不正なリクエストであり、この不正なリクエストを判別できないWebアプリケーションはCSRFの脆弱性があると言えます。
###CSRFの脆弱性があると発生しうる被害
CSRFの脆弱性があると、以下の被害を受ける可能性があります。
・利用者アカウントが不正利用される
・利用者のパスワードやメールアドレスが変更される
・利用者の所持している金銭が利用される
##CSRFの仕組み
CSRFが行われる手順
①攻撃者がユーザー情報を盗み出すWebサイトを用意する
攻撃者が、あらかじめ情報を盗むため（セッションハイジャック用）のWebサイトを作成する。
②ユーザーが脆弱性のあるWebアプリケーション上でログインし、セッションIDを取得する
通常通りWebサイトを利用するために脆弱性のあるWebアプリケーションにログインする。
③Webアプリケーションにログインした状態で悪意あるサイトにアクセスする
脆弱性のあるwebサイトから悪意あるWebサイトにアクセスすることでセッションハイジャックが成立し、ログイン情報を攻撃者に盗まれる。
④攻撃者が抜き出したログイン情報をもとに、脆弱性のあるWebアプリケーションへ不正なリクエストを行う
攻撃者がセッションハイジャックによって盗み出したログイン情報を使って、正規利用者になりすまし、不正なリクエスト（商品の購入や金銭の送金など）を行う。

脆弱性のあるWebアプリケーションではこの不正なリクエストを不正か否か判別することができません。
このようにしてCSRFが成立します。
ちなみに、XSSはクライアントサイドでの脆弱性、CSRFはサーバーサイドでの脆弱性の問題です。
##CSRFの対策
###CSRF対策すべき項目の洗い出し
まずはCSRFの対策を行う必要のあるリクエストを知ることが重要です。
CSRFは全てのリクエストに行う必要はありません。
対策が必要なリクエストは他ユーザーから勝手に実行されては困るようなリクエストです。
例えば、ECサイトの購入処理、パスワードの変更処理といったリクエストです。
###具体的な対策方法
正規ユーザーからのリクエストか否か判別する有効な手段が２つあります。
・確定前のパスワード入力
・リスエストへのトークンの埋め込み
#### 対策①パスワードの再入力
重要な処理が確定する前に再度パスワードを入力してもらうようにします。
CSRFの攻撃対象であるパスワード変更に関わるリクエストも現在のパスワードを入力させることにより　CSRF攻撃を防ぐことが可能です。
セッションハイジャックによって攻撃者がログインしている状態ではありますが、パスワード自体がわかっているわけではないため使える方法です。
#### 対策②リクエストへのトークン（秘密情報）の埋め込み
登録画面、注文確定画面などのCSRF対策が必要なページに対して、攻撃者が知り得ないトークンを要求するようにすれば、不正リクエストによる重要な処理は実行されません。

**トークン**
トークンとは1度だけ使用可能なパスワードで、ユーザーのブラウザ上のみに保管されているもの
ユーザーの認証などに用いられるケースが多くあります。
ログインなどの処理を行うと送信者のブラウザで固有のトークンが保存されます。
ほかユーザーから同様のリクエストをするとトークンが異なったり、存在していません。
こうして、不正なリクエストか否かを判別することができます。
ちなみに、Ruby on Railsのフォームであるヘルパーメソッドではこの対策が取られています。

##最後に
**注意点**
お気づきの方もいると思いますが、XSS脆弱性やセッションハイジャック脆弱性が存在することで、このトークンすらも抜き出される可能性があります。
その結果CSRF対策が無意味になってしまいます。
つまり
**セキュリティ対策はあらゆる面で総合的に行う必要がある**
ということです。
どこか1箇所を強化しても、別の弱い場所からその強化した１箇所を突破する糸口がでてくる可能性があるということです。
Dockerのimageを全て削除する

下記のコマンドを実行すればできます。

```
docker rmi -f $(docker images -aq)
```

まず、`image`の削除は`docker rmi <image ID>`でできます。
以下に例を示します。

```
docker rmi e035f93e2af9
```

ですが、これだとたまに消えない`image`があるので、`-f`オプションをつけて強制的に削除します。

```
docker rmi -f e035f93e2af9
```

次に、全ての`image`のIDを表示させるコマンドを示します。

```
docker images -aq
```

`-a`オプションで隠れている`image`のIDも表示させることができます。
`-q`オプションで`image`のIDのみを表示させることができます。

これらを組み合わせて、最初に示した通り、下記のコマンドで全ての`image`を削除することができます。

```
docker rmi -f $(docker images -aq)
```
[JavaScript] 日本語を含んだ文字配列を大量に比較する場合「localeCompare」と「Intl.Collator の compare」のどちらがパフォーマンス良いか検証した

フロントエンドで日本語を含んだ文字配列を比較する手段として、

- `localeCompare`
- `Intl.Collator`の`compare`

の2つがあります。
どちらが、パフォーマンスが良いか検証した際のメモを残します。

# `localeCompare` と `Intl.Collator`の`compare`

本記事記載（ES2020）時点において、
文字列を比較する`localeCompare`というメソッドが提供されています。

- [MDN - String.prototype.localeCompare](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare)

[localeCompareで配列の内容を五十音順ソート](https://note.kiriukun.com/entry/20181129-sort-with-local-compare)の記事にもある通り、
漢字を含めた日本語をソートしたい場合、`localeCompare`を使用する手があります。

が、MDNの`localCompare`の説明を読み進めると、
以下の記載が見つかりました。

> パフォーマンス
> 巨大な配列のソートなど大量の文字列を比較する場合は Intl.Collator オブジェクトを作成し、 compare プロパティで提供される関数を利用すると良いでしょう。

- [MDN - Intl.Collator.prototype.compare](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/compare)

日本語を含めた文字配列を作成し、検証してみました。

# CodeSandboxで検証

- [Faker.js](https://github.com/marak/Faker.js/)
- [テストデータ・ジェネレータ](https://yamagata.int21h.jp/tool/testdata/)

から、1000個の名前ダミーデータ（英字500個, 日本語500個）を用意し、
CodeSandboxで検証用のロジックを書いてみました。

- [CodeSandbox - Intl.Collator localCompareの検証](https://codesandbox.io/s/intlcollator-localcomparenojianzheng-v73xz)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140704/767f62c1-a7c2-e217-e659-5043870191be.png)

- `Intl.Collator Sort`を押下すると、`Intl.Collator`の`compare`を使った比較および時間計測
- `localCompare Sort`を押下すると、`localCompare`を使った比較および時間計測

が行われ、コンソールへ以下のように出力されます。

```js
// 1回目
Object {used: "Intl.Collator", time: 1.8749999981373549, localSamples: Array[1000]}
Object {used: "localeCompare", time: 3.025000001769513, localSamples: Array[1000]}

// 2回目
Object {used: "Intl.Collator", time: 1.8199999976204708, localSamples: Array[1000]}
Object {used: "localeCompare", time: 3.224999996717088, localSamples: Array[1000]}
```

MDNのドキュメント通り、`Intl.Collator`の方が高速にソートできるようです。

# 結論

日本語を含む文字配列を大量に比較する場合は、
`localeCompare`より`Intl.Collator`を使うとパフォーマンスが良いとわかりました。

が、仕様上、`一二三`のような漢字も`一三二`とソートされますので、
注意して使用してください。[^1]

[^1]: 名前に紐づく`ふりがな`のような項目がある場合は、`ふりがな`でソートした方が正確に並び替えられます。

# おわり

以上です。
おかしい、気になった点などありましたら、
フィードバックいただけると助かります。 :pray: 

## 参考記事

- [Qiita - ウェブサイトをグローバル化するために便利なIntl APIの話](https://qiita.com/teyosh/items/b126f21a16b795885067) ... `Intl`系の他機能を紹介されています
- ダミーデータ系
    - [Faker.js](https://github.com/marak/Faker.js/)
    - [テストデータ・ジェネレータ](https://yamagata.int21h.jp/tool/testdata/)
PWM(Pulse Width Modulation，パルス幅変調)

応用情報技術者平成29年秋期 午前21

モータの速度制御などにPWM(Pulse Width Modulation)制御が用いられる。PWMの駆動波形を示したものはどれか。ここで，波形は制御回路のポート出力であり，低域通過フィルタを通していないものとする。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/b38bc523-c9cf-38d0-0ba1-209d582b997c.png)

１、PWM(Pulse Width Modulation，パルス幅変調)は、信号の強度は一定のままパルス信号を出力する時間(width)を長くしたり短くしたりすることで電流・電圧を制御する方式で、インバータの制御方式として用いられています。

PWMとは別に、パルス信号を出力する時間は一定で、信号の強度(振幅)によって制御する方式をPAM(Pulse Amplitude Modulation，パルス振幅変調)といいます。

選択肢の波形のうち、波形の振幅が一定なのは「イ」のみなので、これがPWMの駆動波形として適切です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/b019f2c6-864e-dc31-f4d9-5681d0ef8021.png)



※Pulse パルス　脉冲（波）
※Modulation　変調　調整,調音

※インバータ（英語: Inverter）とは、
直流または交流から、周波数の異なる交流を発生させる（逆変換する）電源回路、またはその回路を持つ装置のことである。逆変換回路（ぎゃくへんかんかいろ）、逆変換装置（ぎゃくへんかんそうち）などとも呼ばれる。制御装置と組み合わせることなどにより、省エネルギー効果をもたらすことも可能なため、利用分野が拡大している。


参照：

インバータ
https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%83%90%E3%83%BC%E3%82%BF


https://www.ap-siken.com/kakomon/26_haru/q21.html
Cloud RunにデプロイしたサイトにRoute53のサブドメインを適用する

# はじめに
ドメインをAWSで管理はしてあるけど、GCPのCloud Runに適用したいと思いやってみたら意外と簡単に適用できたので、忘れないようにするため記事に残す。

# 対象者
AWS Route53にドメインがあり、Cloud Runでも適用したい人

# マッピングの追加
GCPのコンソールにログイン後、ヘッダーの「プロダクトとリソースの検索」に「Cloud Run」と入力してCloud Runのサービスに移動。

サービスのヘッダーに「カスタム ドメインの管理」とあるのでクリック。

そうすると「マッピングを追加」とあるのでクリックして、マッピングしたいサービスと適用したいサブドメインを入力。

入力後、「CONTINUE」を押す。

# 所有権を証明する

「CONTINUE」を押すとウェブマスターセントラルのURLが出てくるので押す。

そこで、レジストラを選択するセレクトボックスが出てくるので「その他」を選択

そうするとTXTレコードが表示されるのでコピーしてAWS Route53にあるドメインに下記のような内容でレコード追加します。

レコード名:適用したいサブドメイン

レコードタイプ：TXT

TTL:サイトに応じた設定値を入力

レコード追加後、ウェブマスターセントラル側にある確認ボタンを押して確認がとれるとマッピングの追加でサブドメインと紐づけることが出来るようになります。

# DNSレコードを更新

マッピングの追加して「続行」を押すとDNSレコード一覧が表示されるので、所有権を証明したときと同じようにDNSレコードを追加して上げてください。

追加後に「完了」を押すとドメイン一覧にドメインが設定されて、処理が開始されます。（自分は4~5分かかりました。）

最終的に緑のチェックマークがつけば完了です。

※完了後も2~3分置かないとカスタムドメインでアクセス出来なかったので注意してください。

# 余談：証明書について

Cloud Runの[カスタム ドメインのマッピング](https://cloud.google.com/run/docs/mapping-custom-domains)のドキュメントを確認したところ

> Cloud Run（フルマネージド）の場合、サービスをカスタム ドメインにマッピングすると、HTTPS 接続用のマネージド証明書が自動的に発行、更新されます。

とあるのでACMのように別で発行する必要は無さそうです。実際マッピングを追加したら、HTTPSになっていました。

# 参考資料
[カスタム ドメインのマッピング](https://cloud.google.com/run/docs/mapping-custom-domains)
[Amazon Route 53 開発者ガイド 基本レコードの値](https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/resource-record-sets-values-basic.html)
実務でも日常でも使える！便利な無料Webツールまとめ

実務でも、日常生活でも使える、便利な無料Webツールを分野別にまとめてみました。

## 1. 翻訳
|名称|説明|
|---|---|
|[Google翻訳](https://translate.google.co.jp/)|言わずと知れたGoogle社製の翻訳ツール|
|[DeepL](https://www.deepl.com/ja/translator)|人工知能システムを開発しているドイツのDeepL社製の翻訳ツール<br>高精度|

Google翻訳がメジャーですが、DeepLもちょこちょこ聞くようになってきました。
英語→日本語でも、たしかに精度はいい気がします。

## 2. 変換
|名称|説明|
|---|---|
|[ひらがな・カタカナ変換ツール](http://tool.muzin.org/hirakata/)|ひらがなとカタカナを相互変換する|
|[フリがなツール](https://www.webtoolss.com/hiragana.html)|漢字をひらがな or フリガナ付に変換する|
|[caseスタイル変換ツール](https://lazesoftware.com/tool/casestyle/)|キャメルケース、パスカルケース、スネークケース、ケバブケースを相互変換する|
|[10進数・16進数変換ツール](http://tool.muzin.org/16/)|10進数と16進数を相互変換する|
|[Text to ASCII Art Generator (TAAG) ](http://patorjk.com/software/taag/)|文字列をアスキーアート化できるツール<br>種類も豊富|


個人的に気に入っているのが、いちばん下のText to ASCII Art Generator。
例えば文字列「Yeah!!」をFont「Star Wars」で変換すると以下のような感じに！

```
____    ____  _______     ___       __    __   __   __  
\   \  /   / |   ____|   /   \     |  |  |  | |  | |  | 
 \   \/   /  |  |__     /  ^  \    |  |__|  | |  | |  | 
  \_    _/   |   __|   /  /_\  \   |   __   | |  | |  | 
    |  |     |  |____ /  _____  \  |  |  |  | |__| |__| 
    |__|     |_______/__/     \__\ |__|  |__| (__) (__) 
                                                                                                    
```

- Linuxログイン時のメッセージ（/etc/motd）
- WEBページの隠しコード

など、遊び心を入れたい時に使えます♪


## 3. 整形ツール

|名称|説明|
|---|---|
|[XML整形ツール](https://tm-webtools.com/Tools/XMLBeauty)|XML整形ツール<br>HTML, CSS, Javascript, JSONの整形の他、データ変換機能も充実|
|[JavaScriptのコード整形ツール](https://lab.syncer.jp/Tool/JavaScript-PrettyPrint/)|JavaScriptの整形ツール<br>HTML, CSS用もあり|
|[ＨＴＭＬ整形ツール（プチ・デバッグ機能付き）](http://u670.com/pikamap/htmlseikei.php)|HTMLの整形ツール<br>不完全なタグ一覧を表示するプチデバッグ機能付き|
|[JSONきれい ～JSON整形ツール～](https://tools.m-bsys.com/development_tooles/json-beautifier.php)|JSONの整形ツール<br>形式の正誤判定もしてくれる|

いちばん上のTM - WebToolsのツール群のみで事足りそうですが、好みもあるので、よさそうなサイトをいくつか載せてみました。
## 4. 計算・測定
|名称|説明|
|---|---|
|[オンラインタイマー](https://online-timer.ja.downloadastro.com/tools/)|オンラインタイマー<br>時間を知らせる音を選べるのも楽しい|
|[オンラインアラーム時計](https://onlinealarmkur.com/ja/)|現在時刻を秒単位で表示してくれる他、アラーム設定も可能|
|[keisan 生活や実務に役立つ高精度計算サイト](https://keisan.casio.jp/)|計算専門のポータルサイト<br>CASIOが運営|

keisan 生活や実務に役立つ高精度計算サイトはTHE 総合サイトといった感じ。
「データ分析」や「利息計算」の他、「江戸の生活」などユニークなものもあって面白い！！


## 5. タイピング
|名称|説明|
|---|---|
|[寿司打](http://typingx0.net/sushida/)|ローマ字タイピング<br>回転寿司を思わせるゲームで楽しみながらタイピングの練習ができる|
|[PTYPING](https://ptyping.com/)|プログラミング言語をタイピングしていくサイト<br>対応言語は、Python, Javascript, PHP, C/C++などなど|

PTYPINGは最近人から教えてもらって感動！
プログラミング言語のとっかかりとしてもいいですね。

## 補足事項など
ツール名=サイト名のところも多いので、サイト名は一律省略してます。
随時追記予定。
オススメあればぜひ教えてください～！
Rails 6で認証認可入り掲示板APIを構築する #7 update, destroy実装

←[Rails 6で認証認可入り掲示板APIを構築する #6 show, create実装](https://qiita.com/rf_p/items/11c1d310f3b67c7f4881)

# updateテストの実装

残り2アクションupdateとdestroyを実装します。

updateは更新処理です。
createができていたら似たようなものなので、大きく詰まることはないはずです。

```diff:spec/requests/v1/posts_controller.rb
...

+  describe "PUT /v1/posts#update" do
+    let(:update_param) do
+      post = create(:post)
+      update_param = attributes_for(:post, subject: "update_subjectテスト", body: "update_bodyテスト")
+      update_param[:id] = post.id
+      update_param
+    end
+    it "正常レスポンスコードが返ってくる" do
+      put v1_post_url({ id: update_param[:id] }), params: update_param
+      expect(response.status).to eq 200
+    end
+    it "subject, bodyが正しく返ってくる" do
+      put v1_post_url({ id: update_param[:id] }), params: update_param
+      json = JSON.parse(response.body)
+      expect(json["post"]["subject"]).to eq("update_subjectテスト")
+      expect(json["post"]["body"]).to eq("update_bodyテスト")
+    end
+    it "不正パラメータの時にerrorsが返ってくる" do
+      put v1_post_url({ id: update_param[:id] }), params: { subject: "" }
+      json = JSON.parse(response.body)
+      expect(json.key?("errors")).to be true
+    end
+    it "存在しないidの時に404レスポンスが返ってくる" do
+      put v1_post_url({ id: update_param[:id] + 1 }), params: update_param
+      expect(response.status).to eq 404
+    end
+  end
...
```

例によってcontroller未実装なのでテストはコケます。

# updateの実装

```diff:app/controllers/v1/posts_controller.rb
...

     def update
-      # TODO
+      if @post.update(post_params)
+        render json: { post: @post }
+      else
+        render json: { errors: @post.errors }
+      end
     end
...
```

ここももはや特に語ることなし。
これでテスト通過するはずです。

# destroyテストの実装

```diff:spec/requests/v1/posts_controller.rb
...

+  describe "DELETE /v1/posts#destroy" do
+    let(:delete_post) do
+      create(:post)
+    end
+    it "正常レスポンスコードが返ってくる" do
+      delete v1_post_url({ id: delete_post.id })
+      expect(response.status).to eq 200
+    end
+    it "1件減って返ってくる" do
+      delete_post
+      expect do
+        delete v1_post_url({ id: delete_post.id })
+      end.to change { Post.count }.by(-1)
+    end
+    it "存在しないidの時に404レスポンスが返ってくる" do
+      delete v1_post_url({ id: delete_post.id + 1 })
+      expect(response.status).to eq 404
+    end
+  end
...
```

postの時と逆で、実行寺にレコード数が1減ることを確認します。
なおポイントとしては、
expectの前にdelete_postを呼んでいることです。

以前記載した通りletは遅延評価をされるので、もしexpectの前にdelete_postが無かった場合、expect内の`delete_post.id`でレコードが生成され、`delete v1_post_url`で1レコード消える。つまりexpectブロック内で+1-1=0となり、レコード数に変化が生まれません。

そのためexpect前にレコードを生成し、expectの中でdeleteが実行されることにより-1レコードとなるわけです。

# destroyの実装

```diff:app/controllers/v1/posts_controller.rb
...

     def destroy
+      @post.destroy
+      render json: { post: @post }
     end
...
```

こちらも非常にシンプル。
今回は短めですが、次にやるseedまで含むと長くなりすぎるのでここまで。


# 続き

→[Rails 6で認証認可入り掲示板APIを構築する #8 seed実装](https://qiita.com/rf_p/items/05e44aa24f10b683fa0e)

【[連載目次へ](https://qiita.com/rf_p/items/a846553c11571f4177eb#%E7%9B%AE%E6%AC%A1)】
MaxでMIDIキーボードを使ってドレミファ

#前の記事
[Maxでどの音を鳴らすかをマウスクリックで切り替える](https://qiita.com/waokitsune/items/69c6d2835ff03a29dd97)

#バージョン
Version 8.1.5（9359645）（64-bit windows）

#もっと直感的に音を鳴らしたい
プログラミングちっくなことをシコシコしていても演奏してる感じがあんまりしない…(´･ω･`)
ということで、MIDI鍵のドの鍵盤を押したらドの音が鳴る、レの鍵盤を押したらレの音が鳴る、というものを作ろう！

#キーボードのパーツ
あ、なんかそれっぽいの発見！**kslider**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d906530c-2f61-e942-a25a-4cc15fa5ef07.png)
とりあえず設置して、MIDI鍵の信号をちゃんと受け取ってるかモニタリングしてみようジャマイカ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/50138383-4c59-d3fb-424b-111a1923ea70.png)
………あれ？MIDI鍵押しても無反応なんだけど……(´･ω･`)

#noteinとmtof、そして鍵盤数の設定
まず、MIDI信号を受け取るオブジェクトが必要と判明！
それが **notein** というオブジェクト。1番目の戻り値がPitch=音の高さとなっております。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/faafd5f2-7981-33b0-0412-7edd283679a5.png)
もっと複雑な設定が必要なのかな？と思ってたけど、案外簡単に実現できそうジャマイカ＾＾
noteinを接続して、MIDI鍵押したら反応した！！！でも出てくる値に違和感……。60って何ぞ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/df9511e7-6661-2311-19e4-c3fe38d5dbca.png)
そう、ksliderの1番目の戻り値は周波数ではなく、 **キーボードの番号** でした。
つまり、 **キーボードの番号を周波数に変換する** やつが必要ってこと！
それをやってくれるのが **mtof** というオブジェクト。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/7ae6b128-0aeb-0d03-3bf1-9054bd155676.png)
表示されている鍵盤数とMIDI鍵の鍵盤数が一致してなかったので、設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/7269a409-5e45-a5eb-432a-3d5942be6469.png)
ここ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/c297c9fe-fa39-8595-cb7b-1dc1b481bb2c.png)

#最終的にはこんな感じ
ksliderは無くても動きました。（このサンプルの場合、noteinの第1戻り値をmtofの第1引数に繋いでも同じこと）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ab260c36-c088-d96d-c047-eb4f1d953bb1.png)

* 鍵盤を離しても音が出っぱなし（MIDI鍵はあくまで音の高さを変えることしかしていない）
* 鍵盤を離した時の信号も拾って音が出ちゃう

なんてまだまだダメな子な部分はあるけど、ひとまずやりたいことの第一段階は達成！ということにするっ！

#次の記事
[MaxでMIDI鍵を離した時の信号（ノートオフ信号）をカット](https://qiita.com/waokitsune/items/18c48f48bcd1bccd035e)
高位合成言語　synthesijer その3


#概要

vistaでsynthesijerやってみた。
helloworldやってみた。
threadで書いてみた。

#ソース

```


public class Hello  extends Thread {
	public byte v = 12;
	public void run() {
		byte i;
		for (i = 0; i < 12; i++)
		{
			switch(i)
			{
			case 0:
				v = 'h';
			break;
			case 1:
				v = 'e';
			break;
			case 2:
				v = 'l';
			break;
			case 3:
				v = 'l';
			break;
			case 4:
				v = 'o';
			break;
			case 5:
				v = ' ';
			break;
			case 6:
				v = 'w';
			break;
			case 7:
				v = 'o';
			break;
			case 8:
				v = 'r';
			break;
			case 9:
				v = 'l';
			break;
			case 10:
				v = 'd';
			break;
			case 11:
				v = '!';
			break;
			default:
				v = ' ';
			break;
			}
		}
	}
}




```

#テストベンチ

```

module test();
	reg clk = 0;
	reg rst = 1;
	reg v_in = 0;
	reg v_we = 0;
	reg start_req = 1;
	reg join_req = 0;
	reg yield_req = 0;
	wire run_busy;
	wire start_busy;
	wire join_busy;
	wire yield_busy;
	wire [7:0] v_out;
	Hello u(.clk(clk), .reset(rst), .v_in(v_in), .v_we(v_we), .v_out(v_out), .run_busy(run_busy), .run_req(run_req), 
			.start_busy(start_busy), .start_req(start_req), .join_busy(join_busy), .join_req(join_req), .yield_busy(yield_busy), .yield_req(yield_req));
	initial
	begin
		$monitor("%s", v_out);
		#10
			rst = 1;
		#10
			rst = 0;
		#300
			$finish;
	end
	always
	begin
		#1
			clk = ~clk;
	end
	initial
	begin
		$dumpfile("test.vcd");
		$dumpvars(0, test);
	end
endmodule





```

#iverilog実行結果

```


VCD info: dumpfile test.vcd opened for output.

h
e
l
o

w
o
r
l
d
!


```

以上。
rails Action Textの実装

#はじめに
自分用メモとして残します。

#環境
* Rails v6.0.3.2
* ruby v2.6.6p146
* node v12.18.3
* yarn v1.22.4

#手順
###1.アプリ作成
MySQLを使ったアプリを作成する。

```
$ rails new actionText -d mysql
```

作成したアプリに移動

###2.scaffold
scaffoldでアプリの雛形を作成する。
※articleはtitleとcontentを持つが、後で追加するためここではtitleのみでOK

```
$ rails g scaffold article title:string
```

###3.DB作成

```
$ rails db:create
```

###4.migrate
```
$ rails db:migrate
```
###5.Action Textインストール

```
$ rails action_text:install
```

###6.migrate
```
$ rails db:migrate
```

###7.アソシエーション
Action Textのデータは専用のテーブルに格納されるためarticleモデルに関連づける必要がある。

```rb:app/models/article.rb
class Article < ApplicationRecord
  has_rich_text :content
end
```

###8.ビューにcontent追加

```rhtml:app/views/articles/_form.html.erb

# 省略
  <div class="field">
    <%= form.label :title %>
    <%= form.text_field :title %>
    <%= form.label :content %>
    <%= form.rich_text_area :content %>
  </div>
# 省略

```

```rhtml:app/views/articles/show.html.erb
<p id="notice"><%= notice %></p>

<p>
  <strong>Title:</strong>
  <%= @article.title %>
</p>
<p>
  <strong>Content:</strong>
  <%= @article.content %>
</p>

<%= link_to 'Edit', edit_article_path(@article) %> |
<%= link_to 'Back', articles_path %>
```

###9.コントローラにcontent追加
contentをparamsパラメータを読み出すメソッドに追加する。

```rb:app/controllers/articles_controller.rb
# 省略
    def article_params
      params.require(:article).permit(:title, :content)
    end
# 省略
```
###10.image_processing
image_processingがないと画像が表示されない。


```rb
gem 'image_processing'
```
```
$ bundle install
```


終了
Rotrics DexArmを使ってみた #2

[Rotrics DexArmを使ってみた #1](https://qiita.com/lumbermill/items/638826797a5d2ee0ff70)の続きです。SDKが出てくる気配がないので、シリアル通信でGCodeを送ってなんとかします。意外と応答が素直だから、これで良いのかという気もしてきました。

```python

#!/usr/bin/env python3
import serial, time

#Serial setting
s = serial.Serial("/dev/ttyACM0",115200)

def w(gcode):
    '''
    Send GCode to Dexarm and wait for the response.
    '''
    print(gcode)
    s.write(gcode.encode('utf-8')+b'\r\n')
    r = None
    while r == None or "echo:" in r:
        r = s.readline().decode('utf-8').strip()
        print(r)  # "ok", "echo:busy" or "beyond limit.."

def wait(ms):
    w('G4 P'+str(ms))

def move(x,y,z):
    cood = ""
    if x != None: cood += "X"+str(x)
    if y != None: cood += "Y"+str(y)
    if z != None: cood += "Z"+str(z)
    w('G0 '+cood)

z1 = 0
z2 = 30

def pick():
    move(None,None,z1)
    w('G0 Z0')
    w('M1000')
    wait(500)
    move(None,None,z2)

def drop():
    move(None,None,z1)
    w('M1001')
    move(None,None,z2)
    wait(500)
    w('M1003')

# Main
def main():
    # Initialize
    w("M1111")
    time.sleep(1)
    move(100,0,30)

    # Pick and move objects in different speeds.
    w("G0 F3000")
    move(100,200,z2)
    pick()
    move(0,-200,z2)
    drop()
    w("G0 F6000")
    move(50,200,z2)
    pick()
    move(50,-200,z2)
    drop()
    w("G0 F8000")
    move(0,200,z2)
    pick()
    move(100,-200,z2)
    drop()

    # back to center
    move(200,0,0)
    s.close()
    print("Fin.")

#Main loop
if __name__ == '__main__':
    main()
```

よく考えたらPythonに固執する必要もないので、Rubyで書き直し始めています。続きは実機が手に入ったら書きます。基本的な操作をgemとかにまとめても良いかもしれませんね。

```ruby
#!/usr/bin/env ruby
# sudo apt install ruby-dev -y
# sudo gem install serialport

require 'serialport'

s = SerialPort.new('/dev/ttyACM0', 115200, 8, 1, 0) # device, rate, data, stop, parity

def w(gcode)
    puts gcode
    s.puts gcode + '\r\n'
    r = nil
    while r == nil || r.start_with?("echo:") do
        # "ok", "echo:busy" or "beyond limit.."
        r = s.readline.chomp.strip
        puts r
    end
end

w("M1111")
sleep(1)
s.close

puts "fin"
```
高位合成言語　synthesijer その２


#概要

vistaでsynthesijerやってみた。
helloworldやってみた。

#ソース


```

import synthesijer.rt.*;

public class Hello {
	public byte v = 12;
	//private byte[] a = new byte[]{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!'};
	@auto public void run() {
		byte i;
		for (i = 0; i < 12; i++)
		{
			//v = i;
			switch(i)
			{
			case 0:
				v = 'h';
			break;
			case 1:
				v = 'e';
			break;
			case 2:
				v = 'l';
			break;
			case 3:
				v = 'l';
			break;
			case 4:
				v = 'o';
			break;
			case 5:
				v = ' ';
			break;
			case 6:
				v = 'w';
			break;
			case 7:
				v = 'o';
			break;
			case 8:
				v = 'r';
			break;
			case 9:
				v = 'l';
			break;
			case 10:
				v = 'd';
			break;
			case 11:
				v = '!';
			break;
			default:
				v = ' ';
			break;
			}
		}
	}
}




```

#テストベンチ


```

module test();
	reg clk = 0;
	reg rst = 1;
	reg v_in = 0;
	reg v_we = 0;
	wire [7:0] v_out;
	Hello u(.clk(clk), .reset(rst), .v_in(v_in), .v_we(v_we), .v_out(v_out));
	initial
	begin
		$monitor("%s", v_out);
		#10
			rst = 1;
		#10
			rst = 0;
		#300
			$finish;
	end
	always
	begin
		#1
			clk = ~clk;
	end
	initial
	begin
		$dumpfile("test.vcd");
		$dumpvars(0, test);
	end
endmodule





```

#iverilog実行結果


```

VCD info: dumpfile test.vcd opened for output.

h
e
l
o

w
o
r
l
d
!
h


```

以上。
Hadoop(ハドゥープ)、MapReduce、Google File System

応用情報技術者平成29年秋期 午前19

Hadoopの説明はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/fdf31b50-12e3-1d21-fe6a-b32281965cb4.png)


１、Hadoop(ハドゥープ)は、ペタバイト級の大規模データの蓄積・処理の分散処理を実現するミドルウェアです。
Googleが論文として発表した分散処理フレームワーク「MapReduce」および分散ファイルシステム「Google File System」を基盤技術に、オープンソースとしてJavaで実装したものです。


２、MapReduceは
巨大なデータセットを持つ高度に並列可能な問題に対して、多数のコンピュータ（ノード）の集合であるクラスター（各ノードが同じハードウェア構成を持つ場合）もしくはグリッド（各ノードが違うハードウェア構成を持つ場合）を用いて並列処理させるためのフレームワークである。


３、Google File System（GFS、GoogleFS）は、
Googleが自社のシステムのために開発した分散ファイルシステムである。大規模なデータセンターに特化した、効率的で信頼性の高いシステムとして設計されている。

・バイトの単位一覧

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/80806653-9cb2-f422-454a-9646f2800ed2.png)






参照：
https://www.ap-siken.com/kakomon/29_aki/q19.html#:~:text=Hadoop(%E3%83%8F%E3%83%89%E3%82%A5%E3%83%BC%E3%83%97)%E3%81%AF%E3%80%81%E3%83%9A%E3%82%BF%E3%83%90%E3%82%A4%E3%83%88,%E3%81%A7%E5%AE%9F%E8%A3%85%E3%81%97%E3%81%9F%E3%82%82%E3%81%AE%E3%81%A7%E3%81%99%E3%80%82

https://ja.wikipedia.org/wiki/%E3%83%9A%E3%82%BF%E3%83%90%E3%82%A4%E3%83%88#:~:text=%E3%83%9A%E3%82%BF%E3%83%90%E3%82%A4%E3%83%88%20(petabyte)%20%E3%81%AF%E3%83%87%E3%83%BC%E3%82%BF%E9%87%8F,%E3%81%82%E3%82%8A%E3%80%811%2C024%E3%83%86%E3%83%A9%E3%83%90%E3%82%A4%E3%83%88%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82
CPUスケジューリングーラウンドロビンスケジューリング方式

応用情報技術者平成29年秋期 午前18

CPUスケジューリングにおけるラウンドロビンスケジューリング方式に関する記述のうち，適切なものはどれか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/0b94c6c1-0a27-7ea1-a25a-35716c49c3cb.png)


１、ラウンドロビンは、
実行可能状態となった順に従ってタスクに一定のCPU時間(タイムクウォンタム)を与えていくタスクスケジューリング方式です。一定時間内に処理が終わらなかったタスクは、実行可能状態の待ち行列の最後尾に移され、CPU使用権が与えられる順番を待つことになります。

・ラウンドロビン (英: Round-Robin) とは、様々な場面で用いられるが、大抵の場合において「何かの役割・出番をたくさんの物事・人員で交替しあう」というような意味で用いる。 例えば、ラウンドロビンパーティとは参加者各自の習慣で小さなパーティを一つずつ参加者がまわって歩くようなパーティのやり方をさす。

例：DNSラウンドロビン
DNSの負荷分散機能です。具体的には、以下のように同じホスト名に対して複数のAレコードを設定することで、アクセスを複数のコンピュータに（単純に順繰りに）振り分けます。

　www IN A 200.x.y.1
　www IN A 200.x.y.2
　www IN A 200.x.y.3


２、優先度順のスケジューリング
リアルタイムシステムでは、定められた時間以内に処理を完了することが求められるので優先度順のスケジューリングが適しています。

３、タイムシェアリングシステム
1台のコンピュータをCPU時間で分割し、複数のユーザで利用できるようにしたシステム



参照：
https://www.ap-siken.com/kakomon/18_haru/q25.html


https://qiita.com/lymansouka2017/items/3f5653c6161650574ac9
Rustの構造体　その1

以下の記事を翻訳して理解した内容をまとめています。

https://doc.rust-lang.org/book/ch05-01-defining-structs.html

構造体の定義には、structキーワードを使用する。
その次に構造体の名前を記入する。
次に中括弧の内側でフィールドを定義する。

```
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}
```

インスタンスを作成する場合は中括弧の中にkey : Valueの形で記載する。
順序は関係ない。

```
let user1 = User {
        email: String::from("someone@example.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };
```

値を参照する場合はドット表記で記載する。

```
    let mut user1 = User {
        email: String::from("someone@example.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };

    user1.email = String::from("anotheremail@example.com");
```

構造体は全体が変更可能でなければならない。

関数の戻り値を構造体にすることもできる。

```
fn build_user(email: String, username: String) -> User {
    User {
        email: email,
        username: username,
        active: true,
        sign_in_count: 1,
    }
}
```

全部のフィールドを記載しなくちゃいけないのはめんどくさい。

## Using the Field Init Shorthand when Variables and Fields Have the Same Name

パラメータとフィールド名が同じならばフィールド名を省略できる。

```
fn build_user(email: String, username: String) -> User {
    User {
        email,
        username,
        active: true,
        sign_in_count: 1,
    }
}
```

## Creating Instances From Other Instances With Struct Update Syntax

通常は古いインスタンスから一部を変更して新しいインスタンスを作成することが多い。
以下はemailとusernameに新しい値を設定するが、それ以外は、上で作成したuser1からの同じ値を使用する。

```
    let user2 = User {
        email: String::from("another@example.com"),
        username: String::from("anotherusername567"),
        active: user1.active,
        sign_in_count: user1.sign_in_count,
    };
```

以下の様に..構文を使用すると、少ないコードで上と同じ事ができる。

```
    let user2 = User {
        email: String::from("another@example.com"),
        username: String::from("anotherusername567"),
        ..user1
    };
```

emailとusernameの値が異なるuser2のインスタンスを作成するが、user1のactiveフィールドとsign_in_countフィールドの値は同じとなる。

## Using Tuple Structs without Named Fields to Create Different Types

タプル構文に似たタプル構造体が定義できる。
タプル構造体にはフィールド名を除いて記載する。

タプル構造体を定義するには、構造体キーワードと構造体名で始まり、その後にタプル内の型が続く。
たとえば、以下はColorとPointという名前の2つのタプル構造体の定義と使用法を示す。

```
    struct Color(i32, i32, i32);
    struct Point(i32, i32, i32);

    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0);
```

blackとoriginはタイプが異なるタプル構造体である。
Colorをパラメータとして受け取る関数は、Pointを受け取る事はできない。

## Unit-Like Structs Without Any Fields

フィールドのない構造体を定義することができる。
これらはユニット構造体と呼ばれている。

### Ownership of Struct Data

上の文字列は&str文字列のスライスタイプではない。
この構造体のインスタンスが全てのデータを所有し、構造体全体が有効である限りそのデータが有効であるため、そのようにしている。

構造体に参照を格納することはできるが、これを行うためには、Rustの機能であるライフタイムを使用する必要がある。

以下はエラーになる。

```
struct User {
    username: &str,
    email: &str,
    sign_in_count: u64,
    active: bool,
}

fn main() {
    let user1 = User {
        email: "someone@example.com",
        username: "someusername123",
        active: true,
        sign_in_count: 1,
    };
}
```

![スクリーンショット 2020-09-12 071427.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624329/4639592d-8873-e608-7d15-60149724cd31.jpeg)
docker イメージを使った squid によるプロキシサーバー

# squid によるプロキシサーバー

https://hub.docker.com/r/minimum2scp/squid の docker イメージを使った場合

Ubuntu 20.04 上で確認しました。

## Ubuntu 側の設定

```
docker run --rm --name proxy-squid -d -p 3128:3128 minimum2scp/squid
sudo apt install -y firewalld
sudo firewall-cmd --zone=public --add-port=3128/tcp  --permanent
sudo firewall-cmd --reload
```

※ 再起動後も自動的に docker container を再起動する場合は以下のように `--restart always` をつけて、`--rm` を外す

```
docker run --restart always --name proxy-squid -d -p 3128:3128 minimum2scp/squid
```


## クライアント

### プロキシサーバー上で試す場合

```
curl  --proxy http://localhost:3128 https://www.yahoo.co.jp
```

### 別のマシンで試す場合

`proxy.address` はプロキシのアドレス

```
curl  --proxy http://proxy.address:3128 https://www.yahoo.co.jp
```
Laravel Homesteadに複数のプロジェクトを構築する方法

参考記事
https://www.hypertextcandy.com/multiple-projects-in-laravel-homestead


# Homestead.ymlファイルを２箇所修正

```
sites:
    - map: homestead.test
      to: /home/vagrant/code/laravel/public
    - map: second.test
      to: /home/vagrant/code/second/public
```

```
databases:
    - homestead
    - second
```

# viでhostsを編集

```
sudo vi /etc/hosts
```

```
192.168.10.10  homestead.test second.test
```

# .env
```
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=second
DB_USERNAME=homestead
DB_PASSWORD=secret
```

# vagrant再起動
```
# vagrant を抜ける
$ exit

# ローカルに戻ったら、vagrantをストップ
$ vagrant halt

# vagrant 再起動
$ vagrant up --provision
```

以上
【GCP】Cloud Functions触ってみた

#これをやってみた
https://blog.apar.jp/web/10611/
・HTTPとか選べるとこがある　とりあえずHTTPで	

生成されたURLにアクセスするとHelloWorldがでるという感じ。

# エラー
・node.jsで作ったらできなかった
pythonでもエラーになるので公式でやる
https://cloud.google.com/functions/docs/quickstart-python?hl=ja
書いてある内容でテストまでコンソールでできるが、URLにアクセスするとエラーになる。

https://qiita.com/toshiaki_takase/items/ce65cd5582a80917b52f
http://wiki.nonip.net/index.php/Gcp/Firebase/CloudFunctions/%E5%9F%BA%E6%9C%AC
このへんにかいてあった。要は権限の問題でした。
Firebaseのやり方だけど、このやり方でCloudFunctionもいける

#参考URL
FnctionとGAE何がちがうの？っておもったらそんな記事があった
https://qiita.com/hnw/items/71f3079852aab73106af
[TensorFlow 2.x (tf.keras)] 乱数シードを固定して再現性を向上


`Tensorflow 2.x` (`tf.keras`)で乱数シードを固定する方法を紹介します。

## 実行環境

* Python: 3.6 | 3.7
* Tensorflow: 2.0 | 2.1 | 2.2 | 2.3
* GitHub Actionsでテスト

テストに使用したコードは[こちら](https://github.com/tokusumi/tf-keras-random-seed)にあります。

## 背景

機械学習の開発において、「学習を再現可能にしたい」や「テスト用に、モデルの初期値を固定したい」などの要求があります。
重みの初期値の違いは学習結果に影響を及ぼすので、初期値を固定できるとこれらの悩みの解消に役立ちそうです。

重みの初期値生成は乱数を利用してます。乱数は乱数シードに基づいて生成されています。TensorFlowはデフォルトでは乱数シードは可変です。よって、毎回異なる初期値をもったモデルが生成されてしまいます。
そこで今回は、乱数シードを固定することで再現性の向上を目指します。


## 乱数シードの固定

TensorFlowに加えて、NumPy、Pythonの組み込み関数のシードも固定します。
まとめると以下の様な乱数固定関数が実装できます。

```python
import tensorflow as tf
import numpy as np
import random
import os

def set_seed(seed=200):
    tf.random.set_seed(seed)

    # optional
    # for numpy.random
    np.random.seed(seed)
    # for built-in random
    random.seed(seed)
    # for hash seed
    os.environ["PYTHONHASHSEED"] = str(seed)
```

これは、以下の様に使用します。ただし、TensorFlowの乱数シード固定だけで十分な場合は、`set_seed`を`tf.random.set_seed`に置き換えてください。

```python
set_seed(0)
toy_model = tf.keras.Sequential(
    tf.keras.layers.Dense(2, input_shape=(10,))
)

# 何らかの処理...

# モデルを再現
set_seed(0)
reproduced_toy_model = tf.keras.Sequential(
    tf.keras.layers.Dense(2, input_shape=(10,))
)
```

`reproduced_toy_model`は先に生成したモデル`toy_model`と同じ初期値 (重みの) を持ちます。つまり、再現されています。

`set_seed`を使用しなければ、`reproducible_toy_model`と`toy_model`は全く異なる初期値をもってしまい、再現性が損なわれてしまいます。

`tf.keras.Sequential` だけではなく、Functional APIやSubClassを利用することもできます。

乱数シードの固定方法 (`set_seed`) をもう少し整理します。

### `tf.random.set_seed` について

`tf.random.set_seed`の挙動は少し注意が必要です。

まず、`tf.random.set_seed`を使用した後で、乱数を使用する関数(`tf.random.uniform`: 一様分布からランダムに値をサンプリング) を何度か使用してみます。

```python
tf.random.set_seed(0)
tf.random.uniform([1])  # => [0.29197514]
tf.random.uniform([1])  # => [0.5554141]  (異なる値!)
tf.random.uniform([1])  # => [0.1952138]  (異なる値!!)
tf.random.uniform([1])  # => [0.17513537] (異なる値!!!)
```

それぞれ異なる値が出力されました。このままでは再現性がなさそうです。
しかし、改めて`tf.random.set_seed`を以下の様に使います。

```python
tf.random.set_seed(0)
tf.random.uniform([1])  # => [0.29197514] (A)
tf.random.uniform([1])  # => [0.5554141]  (B)

tf.random.set_seed(0)
tf.random.uniform([1])  # => [0.29197514] (Aの再現)
tf.random.uniform([1])  # => [0.5554141]  (Bの再現)
```

このように`tf.random.set_seed`が呼ばれた場所を起点にして出力が再現されます(`tf.random.uniform`はランダムに値を出力する関数にも関わらず)。

なので、例えば、モデルインスタンス生成 (Sequentialやfunctional APIやSubClassの利用) の直前に`tf.random.set_seed`を呼ぶようにすると、生成されたモデルは毎回同じ初期値をもってくれます。 

## 補足

TensorFlowには引数にseedを渡せるlayerや関数があります。

しかし、layerやlayerに渡すinitializerの引数を明示的に指定するのはモデルが大きくなってくるとあまり現実的な方法ではないと思います。

また、今回紹介した`tf.random.set_seed`を併用しないとうまく動作しないものがあります。

なので、固定したい箇所が少ない場合でも、まずは`tf.random.set_seed`を試してみて下さい。

## まとめ

TensorFlow 2.x (tf.keras) では、`tf.random.set_seed` を使って乱数シードを固定できます。

特に重みの初期値が同じモデルを毎回生成できるようになるので、再現性の向上が期待できます。

## Ref

- [TensorFlow official document: tf.random.set_seed](https://www.tensorflow.org/api_docs/python/tf/random/set_seed)
- keras (tf.kerasじゃない方)の乱数固定: [kerasで学習が再現できない人へ](https://qiita.com/okotaku/items/8d682a11d8f2370684c9)
- 計算結果の再現性も含めた方法 (但し、速度低下): [Tensorflow2.3のtf.kerasで再現性を確保する](https://qiita.com/temple1026/items/05546696f5dc9828e270)
続：OOPのたとえ話が（略

# 熱いぜ
以前に[こんな記事](https://qiita.com/pff01632/items/bf4b58c92d6047ac2e67)を書いたのだが、久しぶりにOOPネタでトレンドが
~~炎上して~~ 熱く燃えているではないか。そこで、あれからまた少し考え
を整理した結果として、自分の考える抽象クラスとインタフェースは
こんな感じ！という考え方を表明してみたい。あくまでも自分の考えは
こうだ、という表明である。思考はJava的で。
※コードはビルドしてないし概念提示用のためかなり適当です。
# インタフェースとは
JavaのRunnableインタフェースがわかりやすいが、実装したい機能を表す
ハンドル（車のハンドルやバスケットの取手やドアノブのイメージ）だと
考えている。Runnableインタフェースで言うならば

- スレッドとして実装したいメソッドを表現するインタフェース
- スレッドの実装は要求ごとに異なるので好きに実装すればよい

という非常に便利な機能を提供してくれている。実装されているクラスが
何者かは知らなくても、インタフェースの機能は保証されると考えられる
ので、実装者はインタフェースを自由に実装できるし、使用者はメソッド
の機能にのみ着目して使える。

現実にこんな機能を実装することはあり得ないが、意味を表現する手段と
して車のハンドル、というインタフェースを考えてみる。

```CarHandle.java
public interface CarHandle
{
    int turnRight(int angle); //実行後の角度を返す
    int turnLeft(int angle);
    void hold();
    void release(); //ハンドルから手を放し自然動作に任せる
}
```

CarHandleインタフェースは車のハンドル、という機能を表明している。
なので、実装先のConcreteオブジェクトがどんな車でもかまわない。
軽自動車、セダン、ワンボックスなど、オブジェクトの特性に合わせて
実装者がインタフェースの動作を実装すればよい。

また、実装先のConcreteオブジェクトが、CarHandleインタフェースを
実装したハンドルオブジェクトを受け取る、という形にするのもいい。
どんな特性のハンドルかは知らなくてもよいが、インタフェースが表明
する機能は実装されている。

CarHandleインタフェースを実装したメーカー純正ハンドルオブジェクト
とか、俺はカスタムするぜ！[モモステ](https://www.momojapan.com/products/steering/index.html)オブジェクト！みたいな楽しいこと
ができてしまう。
# では抽象クラス(abstract)って何だ？
これは一言で表現するなら、半完成品のキットパーツだと考えている。
例えばだ。私と同年代（と言えばピンときてしまう人はバラさないように）
の人は、自作PCに熱中した人もいるだろう。自分でケース、電源、マザー、
CPU、HDD、メモリモジュール、GPUをパーツ単位で買ってきて、自分好みの
性能やコストパフォーマンスのPCを組み立てて動かすのは、それだけでも
エキサイティングな遊びだった。

そして時は流れ、BTOメーカーが乱立する。Web上で注文内容を購入者の
好みにカスタマイズしたPCを完成品の形で届けてくれる。だがショップに
よってカスタムできる内容はまちまちで、理想スペックにはならないので
そのショップは選ばない、なんてこともあった。

さて（長い前置きだったが）半完成品でPCを売ってくれるBTOショップが
ついに現れた（と仮定しよう、実際にはそんなものはない）。購入者から
見て重要度の低いパーツ（ケースとかマザーとかHDDとか）はそこそこの
スペックを選択でき、重要なコアパーツ（CPU、GPU、メモリモジュール）
はダミーが乗っているPCを売ってくれるショップだ。当然キットパーツの
状態では動作しない（インスタンス化できない）。

だから購入者（実装者）がコアパーツを買ってきて（キットパーツクラス
を継承して）CPUはCore i9、GPUはGeForce RTX、メモリは8GBのDDR4を
4枚載せて32GBで、みたいなPCを作ることができる。

```AbstractPC.java
public abstract class AbstractPC
{
    public int case()  //ケースはBTOで選ぶので実装済み
    {
        //ケースの処理だと思いねぇ
    }
    public int powerUnit() //電源はBTOで選ぶので実装済み
    {
        //電源の処理だと思いねぇ
    }
    public int motherBoard() //マザーはBTOで選ぶので実装済み
    {
        //マザーの処理だと思いねぇ
    }
    abstract int cpu(int model_no); //CPUは自分で買ってくる
    abstract int gpu(int model_no); //GPUは自分で買ってくる
    abstract int memory(int model_no, int nums); //RAMは自分で買ってくる
}
```

こいつを継承してCPU、GPU、メモリモジュールを買ってくる（実装する）
ことで、超コスパPCでもハイエンドPCでも作れてしまう。厳密には高性能
PCを作る場合は電源容量とかケースの排熱効率とか細かい話はあるのだが、
とりあえず考えないことにする。

Abstractクラスの利点・便利さという意味では、すでに固定化しており、
実装しても仕様変更の影響を受けにくいフレームワークの部分だけを実装
しておき、変化に対応したい処理は適応領域に合わせてカスタマイズした
実装をしたい、といった要求に応えられることだと思う。

正直なところ、インタフェースの便利さに比べると抽象クラスは使い所が
難しく、利用頻度は低いという印象を持っている。それでも部分実装済み
でコア部分だけを最適な実装にできる便利さには価値がある。
# ところで・・・
もののついでにいろいろ検索しちゃったりしたのだが、典型的な進化論に
はまっちゃってる人とか割とゴロゴロしていて絶望を禁じ得ない。いやね、
進化論で説明したくなる気持ちはわかるよ。でもさ、犬とか猫みたいな、
何もサービスを提供してくれないオブジェクトを実装しても継承しても、
何が便利なのかさ～っぱりわからんのよ。作る意味が感じられない。

はっきり言うと**「伝わらない」**のだ。インタフェースだの抽象クラスだの
少々入り組んだ概念を説明するのに、プログラミングする自分が得られる
利益が何なのか伝わってこない。それではいかんと思うのだ。

だから、第三者に対してレクチャーする意図で説明するのなら、相手の立場で
**「そうか、こんな便利なことができるんだ」**という感動を生み出さなければ、
レクチャーとしては日本じゃあ二番目だ。感動は記憶に深く刻まれるのだ。
GoのBenchmarkに出てくる関数名の後ろの数字

Goのベンチマークをするときに出てくる
関数名の後ろの数値ってなんだっけとど忘れしたのでメモしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54313/2f10a318-b5d7-2cf1-3116-f2ab5be38cd1.png)

関数名-4 <-この"-4"の事ですね。

これはベンチマークに使ったCPU数です。
なので

```
go test -bench . -cpu 2
```

のようにCPU数を指定すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54313/61b32db7-e8ba-b004-31b0-4882c21f2fa2.png)

ちゃんと変わります。

普段からGo使ってる人にとっては当たり前の事かもしれませんが
使ってないと知らなかったり忘れたりするので。
プログラム初心者にお勧めな本

個人的にだけどすごくわかりやすくて面白い本を見つけた。
それがっっ！「すっきりわかるJAVA入門」っだ！(個人的だからネ！)
「中山 清喬」さんが書かれてる本なんだけどすごいわかりやすかった、、
なんだろ、、えっと、こう、なんというか、、すごい！
まず「カラー」で「かわいいキャラ」が
　書かれてて内容的には
その人たちと一緒に勉強してる感じで面白かった！
初心者がつまずきそうなところもちゃんと詳しく書かれててめっちゃ助かった、、
ほかにも、
C言語,JSP&Servletの本を買ったんだけど
わかんないところの説明とか初心者がつまずきやすい点、もしもこんなエラーが出たら、、
などいっぱいあってすごくよかった(^▽^)
【Git】範囲cherry-pickでmergeコミットを飛ばしたかった

# TL;DR
- `git rebase --onto`を用いるのが良さそうです
  - 参考にさせて頂いた記事(図解付きで非常に分かりやすいです): [merge、rebase実行時のコミットグラフのbefore&after \- Qiita](https://qiita.com/yz2cm/items/60ef738939d1830c7008#4-%E5%AD%90%E9%80%A3%E3%82%8C%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%81%AE%E5%AD%90%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%82%92%E3%82%B9%E3%83%A9%E3%82%A4%E3%82%B9%E3%81%97%E3%81%A6%E3%83%AA%E3%83%99%E3%83%BC%E3%82%B9)

# やりたかったこと
`cherry-pick`で、`merge`コミットを含む範囲のコミットを取ろうとしていました。
一方、この操作をやると`error: commit ${ハッシュ} is a merge but no -m option was given.
fatal: cherry-pick failed`と怒られます。
脳死で`-m`オプションを付けても`merge`コミットは飛ばせませんでした。

# やり方
冒頭に書いた通り`git rebase --onto`で出来ました。
AWS EC2 AmazonLinux2に導入したMailCatcherでLaravelのメールの受け取りを行う

# 目的

- AWS EC2 AmazonLinux2インスタンスに導入したMailCatcherにてLaravelから送られてきたメールを受け取る方法をまとめる

# 前提条件

- AWS EC2 AmazonLinux2インスタンスにLaravelの動作環境が構築されていること。

# 前提情報

- 下記の方法で構築したLaravel環境にMailCatcherを導入し作業を行う。
    - [AWS EC2 AmazonLinux2だけでLaravelのアプリをデプロイする](https://qiita.com/miriwo/items/b39d1ac6289c54cc2cfd)

# 読後感

- AWSのインスタンス内に構築したLaravelアプリから送信されたメールを同じインスタンス内に導入されたMailCatcherで受け取ることができる。

# 概要

1. MailCatcherの導入
1. .envファイルの記載
1. 確認

# 詳細

1. MailCatcherの導入
    1. 下記の方法でAWS EC2 AmazonLinux2にMailCatcherを導入する。
        - [AWS EC2 AmazonLinux2インスタンスにMailCatcherを導入する]()
1. .envファイルの記載
    1. .envファイルのMail設定部分を下記の様に修正する。

        ```.env
        MAIL_DRIVER=smtp
        MAIL_HOST=127.0.0.1
        MAIL_PORT=1025
        MAIL_ENCRYPTION=null
        MAIL_FROM_ADDRESS=admin@gmail.com
        MAIL_FROM_NAME=admin
        MAIL_USERNAME=null
        MAIL_PASSWORD=null
        MAIL_PRETEND=false
        ```
1. 確認
    1. Laravelアプリからメールを送信する。
    1. 下記の様にブラウザでMailCatcherを表示しメールが受信できていることを確認したら作業完了である。

        ![MailCatcher__1_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/8480112f-6ff7-82c0-174c-4bd96bde48ea.png)
Gatsbyで画像を扱う際に注意すべきこと。

何かビルドが重いなと思って調べたら色々と出てきました。

# 問題のコード

Gatsby-imageで画像を呼び出すコードをコンポーネント化したい場合、このように書くことができる。

```javascript
const BadImage = ({ imagePath }) => {
  const data = useStaticQuery(graphql`
    query {
      allFile(filter: { sourceInstanceName: { eq: "images" } }) {
        nodes {
          relativePath
          childImageSharp {
            fluid {
              ...GatsbyImageSharpFluid
            }
          }
        }
      }
    }
  `);

  const image = data.allFile.nodes.find(img => img.relativePath === imagePath);

  return <Image fluid={image.childImageSharp.fluid} />;
};
```

しかしこのように書くと、このコンポーネントを呼び出すごとに画像フォルダにある画像がすべて呼び出される為、画像フォルダの画像が増えれば増えるほど重くなるらしい。
よって、本当に欲しい画像を取得するQueryを書くことが望ましいとされている。

# じゃあどうするの
「じゃあなんすか、何回も同じコード書けばいいんすか」と言われそうだが、この問題はGraphQLが提供しているFragmentを使うことで解決できる。

```javascript
export const getFluidImage = graphql`
  fragment getFluidImage on File {
    childImageSharp {
      fluid {
        ...GatsbyImageSharpFluid
      }
    }
  }
`;
```

# サンプルコード

```javascript:src/components/fragment.tsx
import { graphql } from 'gatsby';

export const getFluidImage = graphql`
  fragment getFluidImage on File {
    childImageSharp {
      fluid {
        ...GatsbyImageSharpFluid
      }
    }
  }
`;

```

```javascript:src/pages/index.tsx
const IndexPage: React.FC<any> = ({ data }) => (
  <div>
    <div>
      <Img fluid={data.image1.childImageSharp.fluid} />
      <Img fluid={data.image2.childImageSharp.fluid} />
    </div>
  </div>
);

export const query = graphql`
  query {
    image1: file(relativePath: { eq: "feelsbadman.png" }) {
      ...getFluidImage
    }
    image2: file(relativePath: { eq: "pase_zasetsu.png" }) {
      ...getFluidImage
    }
  }
`;
```
(型がガバガバなのはご愛嬌)
こうすることによって本当に欲しい画像を取得しつつ、各コードの量も極力減らすことができる。

# 参考文献

- [5 Optimizations to Get Faster Gatsby Builds Today](https://www.netlify.com/blog/2020/06/11/5-optimizations-for-faster-gatsby-builds/)
- [javascript - Reusable Gatsby-Image Component with dynamic image sources - Stack Overflow](https://stackoverflow.com/questions/55122752/reusable-gatsby-image-component-with-dynamic-image-sources)
- [An Introduction To Using Gatsby Image & Gatsby.js V2](https://codebushi.com/using-gatsby-image/)
windowsインストールソフト

## Editor
- Visual Studio Code
 - https://azure.microsoft.com/ja-jp/products/visual-studio-code/
<br/><br/>
- Sakura
 - https://sakura-editor.github.io/


## Diff
- DF
 - https://takuki.com/dennou/71-DF.htm
<br/><br/>
- WinMerge
 - ディレクトリごと比較可能
 - https://winmerge.org/?lang=ja


## DB
- A5
 - DB開発に便利（ER図作成、レコード更新前後比較など高機能）
 - https://a5m2.mmatsubara.com/


## Clipboard
- CLCL
 - クリップボードの履歴を持てる（文字、スクショ画像なども可能）
 - https://www.nakka.com/soft/clcl/


## 圧縮解凍ソフト
- Lhaplus
 - https://www.vector.co.jp/soft/dl/win95/util/se169348.html
<br/><br/>
- 7-Zip
 - 7zファイルの圧縮率が高い
 - https://sevenzip.osdn.jp/


## ブラウザのアドオン
- FireShot
 - フスクロール不要でページ全体のキャプチャ可能
 - https://chrome.google.com/webstore/detail/take-webpage-screenshots/mcbpblocgmgfnpjjppndjkmgjaogfceg?hl=ja