OmniAICreator/Qiita-1.07M huggingface dataset:
ValgrindをMacにインストールするコマンド

現状のバージョンはMacでは使えなくなっているので、以下のgithubからMacで使えるものをbrewでインストールします。

[LouisBrunner/valgrind-macos: A valgrind mirror with latest macOS support](https://github.com/LouisBrunner/valgrind-macos)

```
brew tap LouisBrunner/valgrind && \
brew install --HEAD LouisBrunner/valgrind/valgrind && \
brew upgrade --fetch-HEAD LouisBrunner/valgrind/valgrind
```
swift5でぐるぐる回るやつの回るタイミングが遅れるやつの治し方

## 症状
- swift5
![lag_refresh.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152090/d9be6257-7d83-134d-bfeb-0d22e29cdcc9.gif)

## TL;DR
- swift5で下スワイプでぐるぐるなるやつRefreshControl
- 更新はされるが，ぐるぐるの回転が始まるタイミングが遅かった
- 以下のように直した

### 変更前
```swift
    @objc func refresh() {
        sleep(3)//重い処理を想定
        DispatchQueue.main.async {
            self.tableView.refreshControl?.endRefreshing()
        }
    }

```

### 変更後
- mainじゃないglobalのスレッド？に並列処理として重い処理を投げる(ﾆﾜｶﾅﾉﾃﾞﾖｸﾜｶｯﾃﾅｲ)

```swift
    @objc func refresh() {
        DispatchQueue.global(qos: .default).async(execute: {
            sleep(3)/重い処理を想定
            DispatchQueue.main.async {
              self.tableView.refreshControl?.endRefreshing()
            }
        })
    }
```

## 小話
最近iOSアプリを作っていて，[公式](https://developer.apple.com/documentation/uikit/uirefreshcontrol)を参考にひっぱたら更新するやつを書いていましたが，上記の症状に見舞われググること丸１日に溶かしました．[ここ](https://www.mysamplecode.com/2019/05/ios-swift-uitableview-pull-to-refresh.html)に書いている通りに書いてみたら動いたので同じ苦しみを味わう不幸な日本語圏の人を産まないようにここにメモしておきます．

## (資料) ViewController.swift
```swift
import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        tableView.refreshControl = UIRefreshControl()
        tableView.refreshControl?.addTarget(self, action:
        #selector(refresh),
        for: .valueChanged)
        
        
    }
   @objc func refresh() {
    DispatchQueue.global(qos: .default).async(execute: {
        sleep(3)/重い処理を想定
        DispatchQueue.main.async {
           self.tableView.refreshControl?.endRefreshing()
        }
    })
   }
}
```
EclipseでOne Darkテーマを使う

# 早速ですが使用例
簡単な設定でeclipseの見た目がかなりいい感じに・・・！

![eclipse_one_dark.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459219/7c80dc53-8762-533b-9938-bd8ecd910c07.png)

# 変更手順

### まずは外観をダークに
「ウインドウ」→「設定」→「一般」→「外観」から「ルック＆フィール」を「ダーク」に設定。

### eclipse color themeの設定ファイルを適用

eclipse color themeプラグイン用に作成された設定ファイルは`.epf`と`.xml`形式があり、`.epf`形式はeclipse自体の設定ファイルとして、`.xml`形式はeclipse color themeプラグインをインストールしてその中の1テーマとして使用します。
ただ、`.xml`形式は再起動時にテーマが読み込まれなくなってしまう不具合があるため、今回は`.epf`形式を使用。

one dark風テーマを公開されている方は複数いらっしゃいますが、ここではgithubでkenstuddyさんが公開されているepfファイル[^1]をダウンロードし、「ファイル」→「インポート」→「一般」→「設定」からインポートします。

# ちなみに
ネット上で公開されているテーマで満足できない場合はeclipse color themeの公式サイトで自作も可能です。[^2]

# 参考
[^1]: github kenstuddy/eclipse-one-dark-theme
  https://github.com/kenstuddy/eclipse-one-dark-theme/blob/master/theme-54613.epf

[^2]: Eclipse Color Themes で自分好みのテーマを作る【目に優しい？】
  https://oza-note.xyz/eclipse-color-themes
Smart lock for Password on Androidを実装するときに気をつけるところ


Smart lock for Password on Android(以下Smart lock)が出たのは2015年です。

当時実装して、これから新しいアプリにSmart lockを追加するときに気をつけるポイントを２つ記載しておきます。

# Clientが変わった


現在は[CredentialsClient](https://developers.google.com/android/reference/com/google/android/gms/auth/api/credentials/CredentialsClient)ですが、以前は[GoogleApiClient](https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient)でした。
どうもGoogleApiClientで保存した情報はCredentialsClientからは取れないようです（違ったら教えて下さい)

# 別のアプリの情報を取得する手段が変わった

https://developers.google.com/identity/smartlock-passwords/android/associate-apps-and-sites

>Publish the app to Google Play Store. It needs to be released in the public channel for associations to be picked up.

現在はこのようにGoogle Play Storeに公開してくださいとあるのですが、以前はオープンβに公開してくださいとありました。
長らくドキュメントが更新されず、なぜ別アプリの情報が取得できないのか不明でした。
Composer updateでmemory-limit-errorsになる場合の対処方法


## Composer update実行時のmemory-limit-errors対象方法

### エラーの内容

```
PHP Fatal error:  Allowed memory size of 1610612736 bytes exhausted (tried to allocate 134217736 bytes) in /usr/share/php/Composer/DependencyResolver/RuleSet.php on line 84

Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 134217736 bytes) in /usr/share/php/Composer/DependencyResolver/RuleSet.php on line 84

Check https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors for more info on how to handle out of memory errors.[frontapps@localhost smartcity-dashboard-service]$ compCOMP
```

### 対処方法

<strong>composer updateコマンドの頭に以下のようにMemory limitの条件をつける。</strong>

```
COMPOSER_MEMORY_LIMIT=-1 composer update
```
40代おっさんEBSを勉強してみる

#40代おっさんEBSを勉強してみる。
##本記事について
本記事はAWS初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。
##EBSとは
EC2にアタッチしてして使用する外付けディスク

##EBSの使用ルール
・EC2にアタッチして使う。
＊アタッチとはEC2にくっつける意味、外すことをデタッチと言う。
・EC2に複数つなげることも可能
・同じアベイラビリティーゾーンでないと駄目である。
・他のEC2と共有することはできない。
＊補足
EBSマルチアタッチなるものがあるそうです。それだと共有できるみたいです
<https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-volumes-multi.html>
##EBSの種類
###SSDタイプ(高価で高速）
####汎用 SSD(gp2)
・ディフォルトでアタッチされる。
・何もなければこちらを使う。
・開発環境で使う
####プロビジョンド IOPS SSD(io1)
・汎用SSDより高性能
・特別な使用要件があるときに使用すると良いと思います。
・gp2 の 補強で使う
###HDDタイプ（安価で読み書きが遅い）
####スループット最適化 HDD(st1)
・ビックデータなどデータをため込むタイプに適している。
・大規模ログ分析
・SSDより料金が低い
####Cold HDD(sc1)
・保管用のタイプ
・料金が非常に安い
・バックアップ、アーカイブ
##### ボリュームタイプの違い
コスト最適化という観点で最適なモノを選ぶ。
SSD / gp2 : 1GB ～ 16TB,高い
SSD / io1 : 4GB ～ 16TB,高い
HDD / st1 : 500GB ～ 16TB,安い
HDD / sc1 : 500GB ～ 16TB,安い
*point
HDD の ボリュームは最低容量 500GB であり
一見して費用対効果が高いように思えるが
個人利用レベルのアプリケーション開発であれば SSD のほうがよい。
##### スループットの違い
スループット最適化 HDD(st1) : 500MB/s
Cold HDD(sc1) : 250MB/s

プロビジョンド IOPS SSD(io1) : 1,000MB/s
汎用 SSD(gp2) : 128MB/s ～ 250MB/s

##EBSのバックアップついて
・EBSはデータを保管しているためバックアップをしっかりとることが重要となります。
###EBSスナップショット
・EBS のデータを Amazon S3 にバックアップする機能です。
・EBSスナップショットには AMI のような、インスタンスを構成するための管理情報は含まれていない。
・データコピーとスナップショットの違いはスナップショットは前のデータの差分のみコピーする。
・あまりスナップショットが多くなると復元に時間がかかる。
*補足
EBSスナップショットは増分バックアップなので、バックアップするのは早いですが、復元する時にはスナップショットごとに戻していくので時間がかる

###AMIでバックアップ
・EC2、EBSを含んだバックアップが可能
・AMIはスナップショットのマッピング情報を持っておりそれを見て復元ができる。

##最後に
勉強してみたがまだ理解がたりないように感じる・・・
がんばるべし・・・

またこの記事はAWS初学者を導く体系的な動画学習サービス「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com/
Unity のプロジェクトに NuGet のパッケージをインポートするエディタ拡張を作ったよ

# まえがき

　例のごとくこの記事は宣伝で、技術的なことは別に書いてます。そちらは以下の通り。

* [GitHub Actions を使った Unity の自動テスト - Qiita](https://qiita.com/kumaS-kumachan/items/d5d44b04b5631154d11a)
* [OnGUI() で重い処理をしたい - Qiita](https://qiita.com/kumaS-kumachan/items/8d669e56feaf6e47adf1)
* [Unity でコードから GUI を作る - Zenn](https://zenn.dev/books/325ed71592f6f5)
* [Unity Package Manager (UPM) に対応した自作パッケージを公開する - Zenn](https://zenn.dev/articles/87de9f8da924e5)
* [Unity で Zip を扱う - Zenn](https://zenn.dev/articles/3b93b3895b9c6f)
* [Unity におけるマネージドプラグインの参照問題 - Zenn](https://zenn.dev/articles/58653297faadb2)
* [DocFX を用いた C# プロジェクトのドキュメント生成 - Zenn](https://zenn.dev/articles/df26e7e5921548)

# 背景

　Unity のプロジェクトで、NuGet のパッケージを使用したいときは [GlitchEnzo/NuGetForUnity](https://github.com/GlitchEnzo/NuGetForUnity) を利用すれば基本的には問題ない。そう、基本的には。例えば、ネイティブプラグインには対応しておらず（[issue](https://github.com/GlitchEnzo/NuGetForUnity/issues/14) にある通り、対応しなさそう）、パッケージの参照が違うバージョンであれば、問題のないバージョンの参照であってもエラーが発生する。そのため、私が使うには不十分であった。
　そこで、私は NuGetForUnity が動作した後に処理をするようなエディタ拡張を考えたが、そもそも動作した後って取れなくない？（NuGetForUnity は .dll で配布されるため）と思い、どうせだからと一から開発することにした。

# 成果物

　二か月でできた。（本業が大変だったから実質一か月だけど。）こんな感じ。[kumaS-nu/NuGet-importer-for-Unity](https://github.com/kumaS-nu/NuGet-importer-for-Unity)

![Demo](https://raw.githubusercontent.com/kumaS-nu/NuGet-importer-for-Unity/main/docs/images/Demo.gif)

## 概要

>NuGet importer for Unity は高速で使いやすく、非常に強力に NuGet のパッケージを Unity へ導入できるようにするエディタ拡張です。 また、ネイティブプラグインに対しても完全に対応しております。 （GlitchEnzo/NuGetForUnity に影響を受けましたが一から作ってます。）

　なんか英語の文章を翻訳した感じになってしまった。(-ω- ?)

## 特徴

>- 非同期を活用した高速な動作
>- 強力な依存関係解決
>- ネイティブプラグインに対する完全な対応
>- わかりやすいUI
>- UPM対応・unitypackageあり
>- [GlitchEnzo/NuGetForUnity](https://github.com/GlitchEnzo/NuGetForUnity)との互換性あり

　基本的にはこんな感じです。UI については Visual Studio 付属の NuGet を~~パク~~参考にしました。あと、やっぱり NuGet のパッケージ情報（特にアイコン）を取得する速度がネックだったので非同期にしました。（UI に非同期のところを入れるのはちょっと気をつけないといけなかったりする。）

## 導入法

　UPMを使っても、unitypackage で導入してもいいです。unitypackage の方は dll 化した状態でパッケージにしてます。具体的な方法は [Readme](https://github.com/kumaS-nu/NuGet-importer-for-Unity/blob/main/README_jp.md) を読んでください。

# あとがき

　今から Unity のプロジェクトに NuGet のパッケージをインポートするならぜっっっっったいこっちの方がいいです！！！！！サクサク動くし、UI 親切だし、問題なく動くので。（NuGet のパッケージを作る・公開するのであればどうぞ [GlitchEnzo/NuGetForUnity](https://github.com/GlitchEnzo/NuGetForUnity) をお使いください。）
　感想とか Twitter とかでつぶやいてこのプロジェクト拡散してくれると嬉しいです！
Amazon Pollyで合成したmp3をHTML5 audioコンポーネントで再生するまで

text -> Polly -> mp3 -> DynamoDB -> api response -> blob -> html5 audio
をやっていきたいと思います。
リアルタイムのAPIに音声合成を組み込む場合の実装例になります。

## 環境
- AWS Lambda + Boto3
- Vue.js

## 前提
S3にファイルを保存するのではなく、バイナリとしてDynamoDBに格納します。
合成音声が短い文章である場合、この方法は十分に有効です。

## Pollyで音声を合成
lambdaからboto3で使っていきます。
リアルタイム変換を行いますが、200文字でもAPIに組み込めるレベルの応答時間(1,000ms程度)です。
ポイントは`response['AudioStream']`がStreamingBodyクラスになります。
https://botocore.amazonaws.com/v1/documentation/api/latest/reference/response.html

```python
def text_to_speach(text):
    polly = boto3.client("polly")

    response = polly.synthesize_speech(
        Text=text,
        OutputFormat="mp3",
        VoiceId="Mizuki")
    
    return response["AudioStream"].read()
```

## DynamoDBへの格納
Pollyで変換したmp3のバイナリデータをDynamoDBに格納すると、バイナリ型として格納されます。
これはBase64でエンコードされたバイナリデータになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491627/fda821cf-915d-81ee-8653-d5e16dcac009.png)

## BlobURLの作成
DynamoDBに格納されたデータを何らかのAPIを通じてクライアントで取得します。
この際まだ音声データはBase64でエンコードされたバイナリデータです。
これをBlob形式に変換するには、以下のようにします。
ポイントは
- base64をデコードしてUnit8Arrayを作る
- Unit8Arrayから`audio/mpeg`を指定してBlobを作る
- BlobからBlobURLを作る
となります。

```typescript:
private base64ToBlob(base64Data) {
    const byteCharacters = atob(base64Data)
    const byteNumbers = new Array(byteCharacters.length)
    for (let i = 0; i < byteCharacters.length; i++) {
      byteNumbers[i] = byteCharacters.charCodeAt(i)
    }
    const byteArray = new Uint8Array(byteNumbers)
    const blobUrl = URL.createObjectURL(
      new Blob([byteArray], {
        type: 'audio/mpeg',
      })
    )

    return blobUrl
  }
```

## 再生
あとはこのBlobURLをaudioコンポーネントのsrcに指定してください。(以下はVueの場合)
`<audio v-bind:src="srcBlobUrl" autoplay />`


## まとめ
- Pollyのリアルタイム音声合成はAPIに組み込めるくらい速い
- DynamoDBにバイナリをBase64エンコードで格納することができる
- Base64をオンメモリでBlobに変換してaudioコンポーネントに利用できる
Ionic の使い方

インストール

```bash
sudo npm install -g @ionic/cli
```

プロジェクトの作成

```bash
ionic start ex01 tabs
```

サーバーのスタート

```bash
cd ex01
ionic serve
```

外部からアクセスするには、

```bash
ionic serve --host=0.0.0.0
```
ブラウザーでアクセス
>Local: http://localhost:8100
>External: http://192.186.1.8:8100

![ionic_bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/854e8c3c-b4f9-856e-eae4-3a698d1d151c.png)

タブを改造してみます。

```html:src/app/tabs/tabs.page.html
<ion-tabs>

  <ion-tab-bar slot="bottom">
    <ion-tab-button tab="tab1">
      <ion-icon name="home"></ion-icon>
      <ion-label>ホーム</ion-label>
    </ion-tab-button>

    <ion-tab-button tab="tab2">
      <ion-icon name="search"></ion-icon>
      <ion-label>検索</ion-label>
    </ion-tab-button>

    <ion-tab-button tab="tab3">
      <ion-icon name="person"></ion-icon>
      <ion-label>プロフィール</ion-label>
    </ion-tab-button>
  </ion-tab-bar>

</ion-tabs>
```

![ionic_feb22_aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/3a62c019-0ad3-7f09-6ce7-ca43379cbced.png)


Tab 1 のページを改造します。

```html:src/app/tab1/tab1.page.html
<ion-header [translucent]="true">
  <ion-toolbar>
    <ion-title>
      ホームのタブ
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content [fullscreen]="true">
  <ion-header collapse="condense">
    <ion-toolbar>
      <ion-title size="large">Tab 1</ion-title>
    </ion-toolbar>
  </ion-header>

  <app-explore-container name="ホームページ"></app-explore-container>
</ion-content>
```

![ionic_feb22_bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/b82e1aa8-387c-1dfd-18af-3841b399669d.png)
【Rails】定数を定義したらとりあえず freeze しておく 

## はじめに

~~~ruby:
# 定数を定義した例
ARASHI_MEMBERS = ['大野', '松本', '二宮', '桜井', '相葉'].freeze
~~~

上記のように Rails で定義した定数は基本的に freeze しておくのがベストです。

不用意に変更されることを防げます。

freeze しておくと、もし `ARASHI_MEMBERS` に破壊的な変更が行われようとした時に FrozenError を起こしてくれます。

~~~irb:
irb(main):001:0> ARASHI_MEMBERS << '木村'
Traceback (most recent call last):
        4: from /Users/dan/.rbenv/versions/2.7.1/bin/irb:23:in `<main>'
        3: from /Users/dan/.rbenv/versions/2.7.1/bin/irb:23:in `load'
        2: from /Users/dan/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/irb-1.2.3/exe/irb:11:in `<top (required)>'
        1: from (irb):2
FrozenError (can't modify frozen Array: ["大野", "松本", "二宮", "桜井", "相葉"]

~~~

なので `ARASHI_MEMBERS` を呼び出した時はいつでもこの5人であることが保証されます。

## 応用① freeze した定数を変更して使いたい時


もし ARASHI_MEMBERS を変更して使いたい時は `dup` メソッドを使いましょう。 freeze されていない コピーを作れます。

~~~irb:
irb(main):001:0> tmp_arashi_members = ARASHI_MEMBERS.dup
irb(main):002:0> tmp_arashi_members << '木村'
=> ["大野", "松本", "二宮", "桜井", "相葉", "木村"]
~~~

※ ちなみに dup せずに変数に定義して変更を行うとやはり FrozenError が発生します。


## 応用② ネストされた Array や Hash を freeze したい時

ちなみに上記の freeze メソッドはネストされていると深くまで完全に機能しません。

~~~irb:
irb(main):001:0> JOHNNYS_MEMBERS = {arashi: ["大野", "松本", "二宮", "桜井", "相葉"] , kat_tun:['亀梨', '上田', '中丸']}.freeze
irb(main):002:0> JOHNNYS_MEMBERS[:arashi] << ' 木村'
=> ["大野", "松本", "二宮", "桜井", "相葉", " 木村"]
irb(main):003:0> JOHNNYS_MEMBERS
=> {:arashi=>["大野", "松本", "二宮", "桜井", "相葉", " 木村"], :kat_tun=>["亀梨", "上田", "中丸"]}
~~~

定数のネストした配列に変更を加えましたがエラーが出ませんね。

ネストの深くまで freeze させるためには、 `gem 'ice_nine'`  の `deep_freeze` メソッド を使います。(導入方法は[こちら](https://github.com/dkubb/ice_nine))
※ 他にも同じような gem はあると思いますので何を使っても大丈夫です。

変更を加えようとするとちゃんとエラーが出てますね。

~~~irb:
irb(main):001:0> JOHNNYS_MEMBERS = {arashi: ["大野", "松本", "二宮", "桜井", "相葉"] , kat_tun:['亀梨', '上田', '中丸']}.freeze
irb(main):002:0> JOHNNYS_MEMBERS[:arashi] << ' 木村'
Traceback (most recent call last):
        4: from /Users/dan/.rbenv/versions/2.7.1/bin/irb:23:in `<main>'
        3: from /Users/dan/.rbenv/versions/2.7.1/bin/irb:23:in `load'
        2: from /Users/dan/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/irb-1.2.3/exe/irb:11:in `<top (required)>'
        1: from (irb):8
FrozenError (can't modify frozen Array: ["大野", "松本", "二宮", "桜井", "相葉"])
~~~


## 応用③ ネストされた Array や Hash の定数を変更して使いたい時

`deep_dup` メソッドを使いましょう。 ※ こちらは Rails に標準で備わっています。

~~~irb:
irb(main):001:0> JOHNNYS_MEMBERS = {arashi: ["大野", "松本", "二宮", "桜井", "相葉"] , kat_tun:['亀梨', '上田', '中丸']}.deep_freeze
irb(main):002:0> tmp_johnnys_members = JOHNNYS_MEMBERS.deep_dup
irb(main):002:0> Jtmp_johnnys_members[:arashi] << ' 木村'
=> ["大野", "松本", "二宮", "桜井", "相葉", " 木村"]
irb(main):003:0> tmp_johnnys_members
=> {:arashi=>["大野", "松本", "二宮", "桜井", "相葉", " 木村"], :kat_tun=>["亀梨", "上田", "中丸"]}
~~~
UnityChan Autodesk FBX Loader

準備するもの

- SD_UnityChan-1.unitypackage
 - Assets/UnityChan/Models/
  - unitychan.fbx
 - Assets/UnityChan/Models/UnityChanShader/Materials/
  - copy to ./UnityChanShader/Materials/
 - Assets/UnityChan/Models/UnityChanShader/Textures/
  - copy to ./UnityChanShader/Textures/
 - Assets/UnityChan/Models/UnityChanShader/Shader/
  - copy to ./UnityChanShader/Shader/

- ModelData_UnityChan_1_2_1.unitypackage
 - Assets/UnityChan/SD_unitychan/Models/
  - unitychan_SD_humanoid.fbx (rename from SD_unitychan_humanoid.fbx)
 - Assets/UnityChan/SD_unitychan/Models/Materials/
  - copy to ./UnityChanSD/Materials/
 - Assets/UnityChan/SD_unitychan/Models/Textures/
  - copy to ./UnityChanSD/Textures/
 - Assets/UnityChan/Models/UnityChanShader/Shader/
  - copy to ./UnityChanSD/Shader/
【AWS認定試験】SOA-C01取得しました

# はじめに
先日、SOA-C01(AWS認定デベロッパーアソシエイト)に合格した為、やったことを残します。
近々SOA-C02も公開されるようですね。(2021-02-22現在)
[近日公開の AWS 認定][link-1]
[link-1]:https://aws.amazon.com/jp/certification/coming-soon/

# 勉強期間(受験時の状態)
勉強時間：だいたい10時間程度

今までに取得したAWSの資格：CLF,SAA,DVA
(以下に詳細があります)
[新卒1年目が1.5ヶ月でAWS認定 クラウドプラクティショナーを取得するまで][link-2]
[【AWS認定試験】SAA-C02取得しました][link-3]
[【AWS認定試験】DVA-C01取得しました][link-4]

[link-2]:https://qiita.com/t_tsuchida/items/3d43385f7348f1702ca8
[link-3]:https://qiita.com/t_tsuchida/items/21f8c40244a53f3e37f9
[link-4]:https://qiita.com/t_tsuchida/items/1fed9d8e18ca39291683

# 試験対策
### Udemy
以下の問題集をじっくりと解きました。
[AWS 認定SysOpsアドミニストレーター アソシエイト模擬試験問題集（全4回分260問）][link-5]
[link-5]:https://www.udemy.com/course/aws-sysops-53195-q/

実際に試験を受けてみて、難易度としては問題集のほうが難しいと感じました。
問題文のレベル感は似ているのですが、選択肢に似通ったものが多く、本番より絞り込みが難しいです。

受験時の受講回数と点数(%)は以下の通りになります。
模擬試験1：2周(46→81)
模擬試験2：2周(56→87)
模擬試験3：未着手
模擬試験4：未着手

方針として、
1周目解き終わったらすべての問題の回答を読み込む→わからない単語、サービスを調べる
2周目は間違えた問題の回答を読み込む
ということを意識して進めました。

こちらの問題集はほかのアソシエイト系問題集と異なり、本番の問題と内容が離れている印象を受けました。したがってこちらの問題集一本で受験しようとすると合格は安定しないと思います。

# 学習内容を振り返り印象に残ったリソース
- Trusted Advisor

- Amazon Inspector
- CloudTrail
- Systems Manager
    - System Manager Agent
- Amazon CloudWatch
    - CloudWatch Agent
    - logs
- Config
- WAF
- Shield
- GuardDuty
- インスタンスユーザデータ
- VPCフローログ
- Organizations
- ACM

# まとめ
実運用を想定した問題が多い印象がありました。
それぞれのサービスでどのようなログがでて、そのログを取れるサービスは何なのか、インシデントが発生した際にどのサービス使って状況を確認すればいいのかくらいは押さえたほうが良いかと思います。
アソシエイトのラスト試験ということで割と準備せずに受けてしまったせいで点数は低かったのですが、無事合格できてほっとしました。
これにてアソシエイト系を3冠しました。アソシエイト体感の難易度としてはSAA>SOA>=DVAくらいだと思います。
关于VAE在自然语言处理上的应用的一些思考

### 前言

我这几天才开始在qiita上发记事，不单止是为了分享实验成果，更重要的是通过语言为自己混乱的思维引入结构。这几天的记事大部分是关于VAE。第一次听说VAE已经是半年前在京都的时候，我为它的自动生成能力而折服，经过几个月的学习，我终于有能力用手边的工具搭建项目开展实验，而VAE的本质也逐渐在我的凝视下展示自身。

在探究研究方向的时候我就突发奇想，能不能像word2vec一样，对句子生成的embedding进行向量操作呢？ 可是5年前已经有人想过这个问题了，而成果便是这篇paper： Generating Sentences from a Continuous Space。第一作者隶属谷歌，同时也是指针网络的创造者。

VAE最大的特点是可以提供我们一个检视潜在空间=检视输入数据同构性的手段。所以我们先来看看论文展示的成果如下图：

![Screenshot from 2021-02-22 11-42-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/079922e4-19c6-ee3e-80a2-4be6787b61aa.png)

我们可以看到两个句子间确实能产生平滑的迁移。这是非常震撼人心的。如论文所言，这意味着我们拥有了量化句子与句子之间同构性的工具。

word2vec在2012年的时候带给自然语言处理领域强烈的震撼，透过w2v的视角来看，句子VAE实际上可以理解成w2v在句子上的应用。因为两者的主题是一致的： 潜在空间操作。

### BERT

句子VAE可以用来填补句子中缺失的词语，这一下子就让我想起了BERT。BERT现在如日中天，它的训练方式正是填补句子的缺失词语。

BERT可以被用作句子VAE的encoder吗？我认为答案是可以，但是很难。我们可以用CLS token的输出作为句子在潜在空间的向量，然后解码——这正是困难所在，我唯一能想到的方法是用RNN一个字符一个字符地输出，直到完成整个句子。为什么我们不以单词为单位输出呢？因为BERT不是static embedding，单词在BERT里没有固定的向量表示。那么我们能借用类似word2vec的static embedding来训练吗？答案是可以。可是，无论是一个字符一个字符地输出，还是借用w2v的词汇表输出，都显得非常tricky，因为输出的结果跟bert完全无关。

BERT能够将句子编码到潜在空间，可是却丧失了解码的能力。这是抛弃static embedding的一个后果，是值得我们反思的。

### QA上的应用

其实我重燃对VAE的兴趣的原因是，之前和一个同样研究NLP的网友聊研究方向，他做的是QA，想要用VAE产生的潜在空间来自动生成更加丰富的答案。

这里我看到的是一个VAE的变种应用，甚至可以说它们已经不再是AE，因为香草AE的目标首先是重建输入，而在问答上的应用，输入是问题，输出是回答。在这样的对比的张力下，我再次发现了AE的一个特点，那就是假定输入和输出存在唯一的对应关系。这个假设在图像重建上很好理解，输入和输出确实是一一对应的，而在QA的应用上则显得比较强硬——一个问题只能对应到一个固定的回答吗？要记住我们不是在做选择题。虽然VAE引入的随机数让输出的回答变得宽泛了，但是本质上我们的训练还是基于同样的假设。

不过，也许这只是受限于数据库——我们没有同个问题对应多个回答的数据库。但是训练的结果真的能那么称心如意吗？VAE的另一个假设是，原始输入里包含有一种未加区分的联系。两个差不多的问题，可以导致潜在空间邻近的两个点，解码的时候，两者的答案可能会产生混淆。但是由于问题差不多，所以答案混淆倒也是情理之中。

思考的结果是，这确实是一个值得研究的课题。

### highway network

据说encoder和decoder之间要用高速公路网络连接，但是我没有这方面的知识，所以仅作参考。

### 作为总结

经过以上思考，我发现潜在空间确实是一个十分吸引人的主题，我们甚至能称之为自然语言的新大陆。

然后，我最近也在思考static embedding相关的问题，显然本质的吸引力还是源于潜在空间。最后，我们多了一个投身于BERT之前加以犹豫的理由。
JavaScriptで数値をsort()する時の注意

# 配列の数値を昇順で表示したい（小さい順）
Paziaで問題を解いていて「あれっ？」ってなったので記録。
ある配列

```javascript
const arr = ['4','6','3','-10','21','0']
// 配列の中身を「文字列」→「数字」
const num = arr.map(Number)
console.log(num) 
// [4,6,3,-10,21,0 ]
```
があるとする。
これを昇順で表示しようとした際に、以下のようにして失敗。

```Javascript
const newNum = num.sort()
console.log(newNum)
// (6) [-10, 0, 21, 3, 4, 6]
```
このようになってしまうのは、数値は文字列へ変換され、Unicode順になるので小さい順にならないそうです。
よって比較関数を利用します。

```javascript
const newNum = num.sort((a,b) => a - b);
console.log(newNum)
// (6) [-10, 0, 3, 4, 6, 21]
```
このようにすると昇順になります。
ポリモーフィズムを理解したい

# はじめに
ポリモーフィズム自体は何度か聞いたことがあったけど，なんとなくの理解で流していたので，自分の備忘録かつしっかりと言語化することで理解しようということで，簡単にまとめてみました．

# ポリモーフィズムとは？
Wikipediaで調べてみると．．．

>ポリモーフィズム（英: Polymorphism）とは、プログラミング言語の型システムの性質を表すもので、プログラミング言語の各要素（定数、変数、式、オブジェクト、関数、メソッドなど）についてそれらが複数の型に属することを許すという性質を指す。ポリモルフィズム、多態性、多相性、多様性とも呼ばれる。対義語はモノモーフィズム (Monomorphism)、単態性、単相性で、プログラミング言語の各要素が唯一つの型に属するという性質を指す。

簡単に説明すると，
**ある関数（orメソッド）が同じ名前なのに引数・返り値(の型)が異なる**とき，その関数を「ポリモーフィズムな関数」や「多相的関数」という感じでしょうか．

例えば，C++では

```C++
#include <iostream>

void print(int i)
{
   std::cout << "Int:  "<< i << std::endl;
}

void print(double f)
{
   std::cout << "Float: " << f << std::endl; 
}

int main()
{
   print(10); // >> Int: 10 
   print(10.0); // >> Float: 10.0
}
```
のように同じ`print`という名前の関数が引数の型(int or double)によって異なる挙動を示すような場合です．

## ポリモーフィズムの分類
ポリモーフィズムはいくつかの種類に分類できます．

- **アドホック多相; Ad hoc polymorphism**
    - ある関数が，異なる型の引数に対してそれぞれ異なる実装を持つ場合．
    - いわゆる*「多重定義」*(C++でいう「オーバーロード」)
- **パラメータ多相; Parameteric polymorphism**
    - コードが特定の方を指定せずに書かれる事でさまさまな型に対して透過的に使用できる場合
    - C++の「テンプレート template」
    - Javaの「ジェネリクス generics」
- **サブタイピング多相; Subtyping polymorphism (部分型付け; Subtyping)**
    - 共通の上位型を持つ複数の型を，１つの名前で扱う場合
    - オブジェクト指向言語で，親クラスから派生（継承）した子クラスがメソッドの内容を上書き（オーバーライド）する場合

先程示した例は，**「アドホック多相な関数」**の例ということになります．

## ポリモーフィズムの実装
先程示したそれぞれの種類についてざっくりとですが，C++で実装してみます．

- **アドホック多相**

これは先程も実装しましたが，オーバーロードですね

```C++
#include <iostream>
#include <string>

int add(int x, int y)
{
    return x + y;
}

std::string add(const std::string& s1, const std::string& s2)
{
    return s1 + s2;
}

int main()
{
    std::cout << add(1, 2) << std::endl; // >> 3
    std::cout << add("Hello, ", "World") << std::endl; // >> Hello, World
}
```

- **パラメータ多相**

テンプレートで任意の型を許容できるようにする！（雑）

```C++
#include <iostream>

template<typename T>

void print(T t)
{
    std::cout << t << std::endl;
}

int main()
{
   print(10); // >> 10
   print(10.0); // >> 10.0
   print("ten"); // >> ten
}
```

- サブタイピング多相

「継承」して「オーバーライド」って感じですね

```C++
#include <iostream>
#include <string>

// Parent
class Person
{
public:
  std::string name;
  int age;
  Person(std::string name, int age);
  virtual void say_hello();
};


Person::Person(std::string name, int age)
{
  this->name = name;
  this->age = age;
}

void Person::say_hello()
{
  std::cout << "Hello! My name is " << this->name << ", " << this->age << " years old." << std::endl;
}

// Child
class Japanese : public Person
{
public:
  Japanese(std::string name, int age);
  virtual void say_hello();
};

Japanese::Japanese(std::string name, int age) : Person(name, age){};

void Japanese::say_hello()
{
  std::cout << "こんにちは！私の名前は " << this->name << ", " << this->age << " 歳です." << std::endl;
}


int main()
{
  Person p("John", 29);
  Japanese j("太郎", 24);
  p.say_hello();
  j.say_hello();
  return 0;
}
```

後半少し雑になってしまいましたが，実際に実装を見てみることでポリモーフィズムの理解には繋がったと思います．
今後もう少し深堀できていけたらなと思います．
外部キーを貼り直した際のエラー

## 概要

初学者が勉強のため、rails + mysqlで記事投稿アプリを作成中。

article(記事)テーブルに紐づくuserカラムに外部キー制約をつけ忘れていることに気付き、

新たにマイグレーションファイルを作成し、foreign_key: trueを追加した。

capistranoによるデプロイで、migrateの段階でエラーが発生した。

## 解決方法

本番環境において

```jsx
$ RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:drop`
$ rails db:create RAILS_ENV=production
$ rails db:migrate RAILS_ENV=production
```

することで、無事にデプロイができました。

## 詳細とエラー解決時の思考

デプロイ時のエラーメッセージ

```jsx
deploy:migrating
      01 $HOME/.rbenv/bin/rbenv exec bundle exec rake db:migrate
      01 == 20210128023243 AddUserToArticles: migrating ================================
      01 -- add_reference(:articles, :user, {:null=>false, :foreign_key=>true})
      01 rake aborted!
      01 StandardError: An error has occurred, all later migrations canceled:
      01
      01 Mysql2::Error: Duplicate column name 'user_id'
```

むむむ、どうやら外部キー制約をつけたmigrationファイルが悪さをしているようだ、、、。

初めは構文エラーを疑いましたが、ローカル環境では問題なく記事投稿できていることからそれはなさそうだと判断。

本番環境のみでエラーが起きているので、ローカル環境との差異である、既に登録されているデータが問題かな、と思いました。

エラーを見るとDuplicate(複製) coiumn name！とあるし、、、

本番環境に登録されているのはテストデータだけだったので、一旦削除することにしました。

ターミナルから直接Mysqlを操作する経験があまりなかったので、調べながらチマチマ、、

```sql
#datebase名を指定する
mysql> use datebase名;
#とりあえずデータを確認
mysql> select * from articles;
#削除して問題ないので全て削除するぞ
mysql> delete from articles;
```

再度capistranoでデプロイ！しようとしたが、同じエラー、、、

userのデータも削除しないとかぁ

上記と同様の手順で

mysql> delete from users;

よし！デプロイ！！したけど、やはりエラー。。。

Duplicate column name user_idについてもう一度考えてみる。

既にuser_idというカラムがあるところにカラムを追加しようとしている、、、？

データだけでなく、テーブル設計を修正しないといけないことに気づく。

その後、解決方法の手順を踏んで、無事に解決できました！！

## 学び

単純でありがちっぽいエラーでしたが、自分にはたくさん学びがあったように感じます。

- テーブル設計が大事

    そもそも序盤のテーブルを作成していく段階で外部キー制約をつけていたら起こらなかったエラーな訳で、、、。テーブル設計をしっかり行った上で、作成に入りましょう。

- 小さなステップで実装＆確認

    実はこの外部キー制約を修正したのは2週間ほど前。ブランチもマージしていたが、ローカルで動作することを確認してデプロイはしていなかった。昨日、別のブランチをマージしたのでデプロイしたところエラーが発覚。

    今回は２つのブランチで作業内容が全然違ったため、エラーの原因が明確だったが、類似するような作業のブランチだった場合、どちらの作業が原因なのか判断が難しくなるリスクがある。せっかくcapistrano使ってるんだから、横着せずに一つの実装で1回デプロイして、必ず動作確認！(当たり前ですが)

- ターミナルでのMySQLの操作

    ローカルだとGUIのツールを使ってDBの中身を確認してたので、CUIでDBを操作する機会になりました。特にRailsだとActiveRecordでSQLを書くこともないので、一度勉強したはずなのにSELECT * FROM articles;も検索しないと書けなかった、、、。今後はCUIで確認、操作していきます！
Railsチュートリアル第二章でのミス（自分用メモ）

しょうもないミスですが自分の記録として残しておきます。


チュートリアルの第二章のでサーバーを立ち上げようと以下を実行したらエラー発生。

```
$ rails s
```


すると、こんなエラーが出る。

```
/home/ubuntu/environment/toy_app/config/environments/development.rb:64:in `block in <main>': undefined method `config' for ActiveSupport:Module (NoMethodError)
```
一時間調べまわった結果、消しちゃいけないものを消していました。

```config/environments/development.rb

config.file_watcher = ActiveSupport::EventedFileUpdateChecker
```



```config/environments/development.rb
config.file_watcher = ActiveSupport::
```

おそらく自分で気づかないうちに消していたと思われます。
何やってるんだ。。

入力しなおしたら無事サーバーを立ち上げることができました。

操作ミスには十分注意しないといけませんね。
rubyでゲームを作りたい

初心者です。Rubyでゲームを作りたかったのですが序盤ではまりまくったので、メモ書き。

ゲーム作りどころかRubyも始めたばかりなので、取り合えず、Googleで「Ruby ゲーム作る」とかで検索をかけ、https://www.sejuku.net/blog/11266
のサイトに行く。

サイトの順番通りにRuby/SDLをやってみようと思い、Ruby/SDLをダウンロードしてみようと、
https://www.kmc.gr.jp/~ohai/rubysdl_download.html
へ飛ぶも、rubyforge.orgのサイトは消滅しているらしく、最新版をダウンロードすることができない。

で、細かいことは忘れたけど、確か
https://rubygems.org/gems/rubysdl
のサイトでRubysdlの2.2.0をダウンロードして、Rubyの処理系もダウンロードして、
ruby install_rubysdl.rb
を実行するとエラーが出た。

色々調べて、何もわからん、と思いながら
http://blawat2015.no-ip.com/~mieki256/diary/201904211.html
のサイト通りにやってみた。

インストールに成功？したので
Main.rbを実行するも再びエラー。

Zlib.dllがないとrequireができないらしい。
http://touhouotanoblog.blog90.fc2.com/blog-entry-426.html
Zlibのサイトを探してみるもそれらしきものが見つからず、発狂寸前。

というか上のブログを最後まで見てみると、32Bit版のRubyが必要とのことで、32bit版のRubyをダウンロードしに行く。

現在パソコンには64Bit版のRubyと32Bit版のRubyが同居している状況なので、PATHの書き換え（よくわかってない）で32Bit版のRubyが作動するようにする。

その後Main.rbを実行すると、ArgumentErrorが起こる。

調べても何のことだかよくわからないのであきらめた。

（後で気づいたのだが、調べていくうちにRuby/sdl2なるものがあることを知る。もしかしたらこっちならうまくいくのかもしれない。）（これを書いているときに思ったのは、Zlib.dllのコピーをやってないなということである。やってみるか・・・）

再び
https://www.sejuku.net/blog/11266
へ戻り、DxRubyを試してみようと思う。

ひとまずここまで。
[Windows向け] VSCodeでエディタとターミナルを切り替えるショートカットの設定


# 背景

VSCode便利ですね．ただ，デフォルトだとエディタとターミナルの切り替えにキーボードショートカットが割り当てられていないようで，コード修正して実行するたびにキーボードから手をはなさないといけないのが地味にストレスでした．(デフォルトでできるようになっていたらコメントで教えてください:bow:)

@hirogaさんが [VSCodeで軽快なターミナル操作！おすすめショートカット設定](https://qiita.com/hiroga/items/692e53d9d2e032331335) という記事でエディタ - ターミナル間の切り替えショートカットの設定法を教えてくれています．ただ，これはmacOSユーザ向けなので，今回Windows 10向けにキーバインドを変えて設定してみました．

元記事を読めば類推できる内容ではありますが，設定しない方がよさそうなキーコンビネーションもあったので，誰かの参考になればと思い記事にしました．

# ショートカットの設定

設定は基本，元記事に従います．

`ctrl+shift+p` でコマンドパレットを開き，"Preferences: Open Keyboard Shortcuts (JSON)" をを選択します．keyboardなどと入力していくと，候補がサジェストされるので，そこから選ぶ感じです（下の画像では誤字してますね）．元記事では，`Preferences: Open Keyboard Shortcuts File`となっていますが，名称が変わったようです．

![vscode-edit-shortcut.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133233/f8de29ef-df3c-8413-91b5-b71b465792c5.png)

そして，開かれたJSONファイルに下記を書き込みます．

```json
[
    { "key": "ctrl+shift+t", "command": "workbench.action.terminal.newInActiveWorkspace" },
    { "key": "ctrl+shift+enter", "command": "workbench.action.terminal.focus" },
    { "key": "ctrl+shift+enter", "command": "workbench.action.focusActiveEditorGroup", "when":"terminalFocus" },
]
```

機能は下記です

- `ctrl+shift+t` 新しいターミナルを開く
- `ctrl+shift+enter` エディタとターミナルの切り替え


# 改変したショートカットの説明

- macOSでは修飾キーに`cmd+shift`を使っていましたが，Windowsっぽく`ctrl+shift`にしています
- もともと割り当てられていたショートカットがあったので，設定を避けました
  - `ctrl+shift+k` は１行削除
  - `ctrl+shift+w` はWindowを閉じる
- `ctrl+shift+j` は元記事だと `ctrl+shift+k` と対になるショートカットだったので削除しました


# まとめ

WindowsでもよいVSCodeライフを．
M1 Macでasdfを使ってnodejsをインストールしたい (2021/02/22時点)

M1 Macでasdfを使ってnodejsを動かそうとしたら微妙にハマったメモ。

asdfでnodejsをインストールしようとすると

```bash
$ asdf install nodejs xx.xx.xx
```

> Binary not found for version xx.xx.xx

のようなエラーが出る人向け。

# 結論

この記事を書いている2021/02/22時点では、M1 Macに対してnodejsの `arm64` バイナリが提供されていない。 このため、シェルが `arm64` で実行されている場合、 `arm64` のバイナリを取得しようとして失敗する。asdfを `x86_64` で実行することで、 `x86_64` のバイナリを取得できる。

nodejsのインストール時にarchコマンドでアーキテクチャを指定する。

```
$ arch -x86_64 asdf install nodejs xx.xx.xx
```

参考: https://github.com/asdf-vm/asdf-nodejs/issues/189#issuecomment-757048599
pyinstaller でsklearn をインポートするときの注意点

## 概要
pyinstaller を用いて、sklearnを内部で使用するライブラリをバイナリ化したときのこと。

`hook.py` にて

`sklearn`　を `hidden import` しているのにもかかわらず、
実際にバイナリを実行する際、


```
No module name 'sklearn.ensemble._forest'
```

のようなエラーが出てしまっていた。


## 何が起きていたか

実際にバイナリが吐き出されたフォルダに行き、
`sklearn` のフォルダに行くと、


```
root@b87a64080bd4:/myproject# cd sklearn/
root@b87a64080bd4:/myproject/sklearn# ls -l
total 1448
drwxr-xr-x 2 root root    4096 Feb 22 02:42 __check_build
-rwxr-xr-x 1 root root 1429088 Feb 19 10:41 _isotonic.cpython-36m-x86_64-linux-gnu.so
drwxr-xr-x 2 root root    4096 Feb 22 02:42 cluster
drwxr-xr-x 6 root root    4096 Feb 22 02:42 datasets
drwxr-xr-x 2 root root    4096 Feb 22 02:42 decomposition
drwxr-xr-x 3 root root    4096 Feb 22 02:42 ensemble
drwxr-xr-x 2 root root    4096 Feb 22 02:42 linear_model
drwxr-xr-x 2 root root    4096 Feb 22 02:42 manifold
drwxr-xr-x 3 root root    4096 Feb 22 02:42 metrics
drwxr-xr-x 2 root root    4096 Feb 22 02:42 neighbors
drwxr-xr-x 2 root root    4096 Feb 22 02:42 preprocessing
drwxr-xr-x 2 root root    4096 Feb 22 02:42 svm
drwxr-xr-x 2 root root    4096 Feb 22 02:42 tree
drwxr-xr-x 2 root root    4096 Feb 22 02:43 utils
```

のようになっていた。うまくバイナリ化が階層的に行われていたかと思ったが、

```
root@b87a64080bd4:/myproject/sklearn# cd ensemble/
root@b87a64080bd4:/myproject/sklearn/ensemble# ls -l
total 4
drwxr-xr-x 2 root root 4096 Feb 22 02:42 _hist_gradient_boosting
```

こうなっていた。
すなわち、　`/myproject/sklearn/ensemble/_forest`
のようなものは確かに存在していなかった。


## 解決策

`hook.py` の `hidden_import` に

`sklearn.ensemle`
などを使うものはきちんと追加する必要がある。

よくよく考えれば当たり前であるが、
https://github.com/scikit-learn/scikit-learn/tree/main/sklearn/ensemble

ここのソースディレクトリなどをみてもわかるように、
sklearn/ensemble に　`__init__.py` が存在していることからも、
きちんとその階層を`hidden_import` に追加しておくのが必要である。


たぶんpyinstaller をよく理解せずに今まで使っていたのが原因だったが、
一回理解することで次からスムーズに運用できるかなと思った。



以上。
DDoS に対する CDN と WAF の役割


#はじめに
本記事では DDoS 対策を行うためのツールとしてよく検討される CDN(Content Delivery Network) と WAF(Web Application Firewall) について、それぞれどのような対策を行うことが出来て、どのように使い分けるのがよいかを考察してみたいと思います。


# DDoS とは
DDoS とは Distributed Denial of Service attack の略で、システムに対して過大なリクエストを送りつけることによってシステムのダウンや遅延を狙った攻撃です。

DDoS には Syn や Ack パケットを利用した TCP レベルのものや、HTTP レベルの攻撃などがさまざまなレイヤーに対する攻撃があります。

# DDoS 対策の目的
DDoS 対策の目的としては通常は以下のようなものが考えられると思います。

1. 正規のユーザーには中断なくサービスを提供し続ける
2. DDoS が原因で発生したトラフィックをシステムに到達させない
3. DDoS、もしくは DDoS 対策により追加のコストが発生しないことが望ましい



# CDN による DDoS 対策
CDN により可能な DDoS 対策について考えてみます。一般に CDN は HTTP(ポート80, 443) 以外のトラフィックを通しません。そのため対象のサービスを CDN 経由に設定することでレイヤー７以下の攻撃からオリジン環境を守ることができます。

また、CDN は通常のサイトと比べて非常に大きなネットワーク帯域を持っているので、DDoS が発生してもキャッシュ対象のコンテンツであればかなりの規模までは問題なくコンテンツを配信し続けることが出来ます。

ただし、DDoS が原因で発生したトラフィックも通常は CDN の課金対象となります。無条件にただ配信を続けてしまうとサービス断は発生しなかったとしても配信コストが増大してしまいます。
ですので CDN を利用していても DDoS 発生時には適切な設定を行うい CDN レベルで攻撃のトラフィックをブロックすることが重要となってきます。

CDN　レイヤーでの DDoS の対策としてはアクセス元の IP や国情報、User-Agent などの情報を単独、または組み合わせて防御するのが一般的です。攻撃があった際に迅速に対応できるように、関連する情報をあらかじめログへ出力するようにしておいたり、ブロックするための設定を作成しておくことが重要です。

Fastly を利用して DDoS 攻撃をブロックするための設定については[「Fastly で DDoSなどのアタックに備えた設定を追加する」](https://qiita.com/AtsushiFukuda/items/8a1ad37f1aae5ba394c0)でも説明をしています。

また、オリジン環境への直接の攻撃については別途考慮する必要があります。CDN ベンダーが利用 IP のリストを公開していれば、対象 IP 以外からのアクセスは全て拒否をすることなどで比較的容易に防御を行うことが出来ます。

Fastly が利用している IP のリストは以下から確認可能です。
[Fastly の IP アドレス範囲へのアクセス](https://docs.fastly.com/ja/guides/accessing-fastlys-ip-ranges)

# WAF による DDoS 対策

続いては WAF について考えてみます。WAF の基本機能としてはリクエストの内容をチェックし、いわゆる OWASP TOP10 といったようなアプリケーションの脆弱性に代表される攻撃のパターンに合致する場合にリクエストをブロック（または記録）します。

WAF の一般的な導入方法としてはアプライアンス型、ソフトウェア型、クラウド型といったような種類があります。以下非常にざっくりした説明です。

**アプライアンス型** - 専用、もしくはWAF機能を有したファイアウォールをアプリケーションの前段階に設置
**ソフトウェア型** - Webサーバーやアプリケーションサーバーにソフトウェアとして WAF をインストール
**クラウド型** - クラウド上にWAF機能を構築し、クライアントのリクエストをクラウド WAF 上で処理してからWebサーバーに送信します。

**CDN 内蔵型** - CDN が機能の一部として WAF を提供。クラウド型の一種とも言える。

DDoS 対策の観点から WAF を考えてみると、WAF はそもそも量の攻撃に対しての防御ではありません。その性質上リクエストの内容を検閲する必要がありマシンリソースも必要とするため、DDoS のような膨大なトラフィックが発生すると WAF の処理が追いつかなくなってしまう懸念があります。

ただし、最近はリクエストの検閲だけでなく、アクセスコントロールリストによるリクエストのブロックや、レートリミットといった様々な追加のセキュリティ機能を有しているサービスも多いです。
DDoS 対策という意味では純粋な WAF の機能というよりも、そういったアドバンスのセキュリティ機能を利用して防御を検討する方がよいでしょう。



# まとめ

DDoS 対策をうたう WAF ソリューションは増えてきていますし、実際に有効な機能を持ったソリューションもありますが、DDoS という希望の攻撃への対策という意味ではやはりまだ CDN のレイヤーで防御を行う方がよいケースが多いように感じます。

ただし、CDN レイヤーで DDoS に適切に対応するためには CDN が以下のような機能を備えている必要があります。

- 有効な対策を分析するためのログ等の情報が迅速に入手可能なこと
- DDoS を防御するための設定が可能であること
- 追加した設定が迅速に適用されること

CDN レイヤーで適切な防御設定を迅速に追加することで、DDoS 対策の目的で説明した項目が実現可能です。
実際に攻撃を受けてからでは対応が難しいので、攻撃を受ける前に万が一の際の運用を考えておくことが重要になってきます。
作業メモ｜Xcode用（iOSアプリ用）の画像をコマンドラインで生成する

## 背景

XcodeでiOSアプリをつくってみているが、アイコン画像のサイズ、たくさん必要。
手で作るのはさすがに面倒くさい。

## 手を抜くために

下記のテキストファイルを作っておいて、ターミナルにペースト。`SIPS`というコマンドを使っている。
シェルスクリプトを書くのが＜正しい＞と思うけれど、テキストエディタが使えて、ターミナルで狙い通りのフォルダを簡単に開けるなら、この方法が楽だと思う😆

```
sips -Z  40 in.jpg -o 40x.jpg
sips -Z  60 in.jpg -o 60x.jpg
sips -Z  80 in.jpg -o 80x.jpg
sips -Z 120 in.jpg -o 120x.jpg
sips -Z 152 in.jpg -o 152x.jpg
sips -Z 167 in.jpg -o 167x.jpg
sips -Z 180 in.jpg -o 180x.jpg
sips -Z 1024 in.jpg -o 1024x.jpg
```

[![Image from Gyazo](https://i.gyazo.com/11c99713cbc007f872c1d2b56bf100c9.gif)](https://gyazo.com/11c99713cbc007f872c1d2b56bf100c9)

### 前提

- 元になる画像は、`in.jpg`など固定の名前にする
- アウトプット画像のファイル名は、`999x.jpg`など、画像サイズを示す
- とりあえず、Xcodeが警告を出さない程度に揃えた。フルに揃えるにはもう少し必要

## その他

画質を気にするなら、`ImageOptim`というツールを使うのが良さそう。いまは「とりあえず画像がほしい」なのでそこまで凝らない。

iOSのアイコン生成をコマンドラインから実行
https://qiita.com/natsuki_summer/items/bd953b14ce9c9726adea


## 環境

- macOS BigSur 11.1
- MacBook Pro (13-inch, 2020, Four Thunderbolt 3 Ports)
AWS EC2 でfwrite: No space left on deviceが出た時の対処法

## はじめに
ec2内でdocker-compose upをしたら、途中で容量が100%になり、実行中のコマンドが終了しました

```
Failed to write all bytes for _blake2.so
fwrite: No space left on device
```

容量を確認してみる

```
[userName@ip ~]$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/xvda1   8.0G  8.0G   20K  100% /
```

容量を増やすことにしました。

## 容量を増やす方法
ec2インスタンスページに行く
↓
elasticBlockStore>ボリュームをクリック
↓
画面上部のアクションをクリック
↓
ボリュームの変更

今回は8gbから20gbに変更しました。

インスタンスの再起動&ec2@userへのログイン

```
[userName@ip ~]$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/xvda1        20G  8.1G   12G   41% /
```
無事20gbになってました。

参考
https://stackoverflow.com/a/54347393

## 容量を減らす方法

https://serverfault.com/questions/330532/xvda1-is-100-full-what-is-it-how-to-fix

https://www.ivankuznetsov.com/2010/02/no-space-left-on-device-running-out-of-inodes.html
Nx ReactのプロジェクトにOpen-Apiを利用する

Nx ReactのプロジェクトにOpenApiを記載して、Swaggerを利用したLibを作成するやり方。

## TL;DR

libsを作成後、run commandに記載して作成する.


## Steps

__Prerequired__

- Java
- nxでのreactのProject

1. api libを作成する
2. open-api generatorを入れる
3. libsにカスタムコマンドを作成する

## 1. Api Libを作成する

api requestを実施するためのlibs/apiを作成します。

```terminal
$ nx g lib api
```

作成完了後に以下の様なディレクトリになってると思います。

```terminal
$ tree ./libs  -L 3   
./libs
└── api
    ├── README.md
    ├── babel-jest.config.json
    ├── jest.config.js
    ├── src
    │   ├── api
    │   ├── api.ts
    │   ├── base.ts
    │   ├── common.ts
    │   ├── configuration.ts
    │   ├── git_push.sh
    │   ├── index.ts
    │   └── model
    ├── swagger.json
    ├── tsconfig.json
    ├── tsconfig.lib.json
    └── tsconfig.spec.json
```

次に、custom commandを作成します。

## 2. open-api generatorを入れる

通常通りにopen-api cliをインストールします。

ちなみに、javaがはいっていないとコマンドの利用できないので、dockerniseの方もありかなと。

```terminal
$ yarn add -D @openapitools/openapi-generator-cli
```

次にcustom commandを作成します。

## 3. libsにカスタムコマンドを作成する

カスタムコマンドを作成した時に、
__What command would you like to run?__ 
と聞かれますので、利用したいコマンドを記載します。

今回はopen-api generator axiosを利用するので、以下の様に(解説はcliみて)作成していきます。

```terminal
$ nx generate run-commands generate --project=api
? What command would you like to run? node_modules/.bin/openapi-generator-cli generate -g typescript-axios -i libs/api-request/swagger.json -o libs/api-request/src/open-api --api-package=api --model-package=model --additional-properties=withSeparateModelsAndApi=true
```

次にコマンドを利用していきます。

## 4. 使い方

さきほど作成した、コマンドの動作検証を実施していきます。

```terminal
$ nx run api:generate
```

作成が完了するといかの様なディレクトリ構成になるかと思います。

```terminal
$  tree ./libs  -L 3       
./libs
└── api
    ├── README.md
    ├── babel-jest.config.json
    ├── jest.config.js
    ├── src
    │   ├── api
    │   ├── api.ts
    │   ├── base.ts
    │   ├── common.ts
    │   ├── configuration.ts
    │   ├── git_push.sh
    │   ├── index.ts
    │   └── model
    ├── swagger.json
    ├── tsconfig.json
    ├── tsconfig.lib.json
    └── tsconfig.spec.json
```

以上で作成完了です。
利用の仕方は通常のOpenApi Genratorで作成したものと特段変わりません。
レポジトリを見てもらえると、利用の仕方のイメージはつくかと思います。(Envだるくて作成してません。)
[レポジトリ](https://github.com/Ntakuya/react-material-dialog-snackbar/tree/feature/build-command/apps/material/src/app/core/api)
Minecraftサーバーにシェルスクリプトからコマンド入力 #bash #Minecraft #screen

# Minecraftサーバーにシェルスクリプトからコマンド入力する方法

マイクラのサーバーを管理することになったので, シェルスクリプトからコマンドを実行できるようにしました.

## `screen` で実行する

[こちらの記事](https://jyn.jp/minecraft-server-auto-restart/)を参考にしつつ, マイクラを `screen` で実行します.

```bash
#!/bin/bash

screen -UAmdS minecraft java -server -jar server.jar nogui
```

Javaのオプションはそれぞれ良い感じに設定して下さい.
このようにすることで, マイクラサーバーを `screen` 上で起動できます.

`minecraft` の部分はスクリーン名です. 自分の分かりやすい名前に設定しましょう.

## シェルスクリプトからマイクラのコマンドを飛ばす

次にシェルスクリプトからマイクラのサーバーに向けてメッセージを飛ばしてみたいと思います.

```hello.sh
#!/bin/bash

screen -p 0 -S <スクリーン名> -X eval 'stuff "say Hello World!\015"
```

`<スクリーン名>` は上で設定したものに置き換えて下さい.
このようにすると, マイクラのサーバーでプレイしているユーザーに向けてメッセージを送ることができます.

同じように, 以下のスクリプトを実行することで, マイクラのサーバーをシェルスクリプトからシャットダウンすることができます.

```shutdown.sh
#!/bin/bash

screen -p 0 -S <スクリーン名> -X eval 'stuff "stop\015"'
```

`stuff` の後ろの部分がマイクラのサーバーの標準入力に流し込まれるという形で動作します.
なお, `\015` は改行コードです.

## `Raw JSON` が必要なコマンドの実行

ここまでは、[先ほどの記事](https://jyn.jp/minecraft-server-auto-restart/)に書いてあった通りなのですが, マイクラの `title` コマンドを使おうとすると, ダブルクオート(`"`)がうまく入力できず, 苦労しました.

Qiitaでも調べてみると, [同じ悩みを抱えている方](https://qiita.com/twitte_raru/items/9e360a95c63060c95749)を発見しました.

根気よくググり続けていると, [これを解決している海外の記事](https://forums.centos.org/viewtopic.php?t=68624)を発見することができました.

以下のようにすることで, ダブルクオートが必須である `Raw JSON` を引数とするようなコマンドを実行できます.

```notif.sh
#!/bin/bash

screen -p 0 -S mc -X eval 'stuff "title @a title {"'
screen -p 0 -S mc -X stuff \"text\":\"タイトル表示\", \"bold\":true}
screen -p 0 -S mc -X eval 'stuff "\015"'
```

これは, マイクラサーバー上で以下のコマンドを実行したのと同じ処理になります.

```
title @a title {"text":"タイトル表示", "bold":true}
```

1つ目の `screen` コマンドの部分を `Raw JSON` が必要なコマンドに, 2つ目の `screen` コマンドの部分に `Raw JSON` の内容を記入することで, titleコマンドを含む様々なコマンドをシェルスクリプトから実行できるようになります.
また, 他のコマンドは今まで通りのやり方で実行できますので, `playsound` コマンドを併用して, `title` コマンドと同時に鐘の音を鳴らすということも可能です.

それ以外の部分は普通のシェルスクリプトとして動作するため, Unixの `sleep` コマンドや, `cURL` を使ったDiscord WEBHOOKによる通知を併用することも可能です.

以下は再起動用シェルスクリプトの一例です.

```restart.sh
#!/bin/bash

curl -X POST -H "Content-Type: application/json" -d '{"username": "MC Server" , "content": "1時間後に定期再起動を実施します。"}' "https://discord.com/api/webhooks/<WEBHOOKのURL>"

screen -p 0 -S mc -X eval 'stuff "title @a title {"'
screen -p 0 -S mc -X stuff \"text\":\"§6§n§l1時間後§rに§b§n§l定期再起動§rを実施します\"}
screen -p 0 -S mc -X eval 'stuff "\015"'

screen -p 0 -s mc -X eval 'stuff "playsound block.bell.use master @a\015"'

sleep 3600

curl -X POST -H "Content-Type: application/json" -d '{"username": "MC Server" , "content": "サーバーの再起動を開始します。\n再起動は約5分で終了します。"}' "https://discord.com/api/webhooks/<WEBHOOKのURL>"

screen -p 0 -S mc -X eval 'stuff "title @a title {"'
screen -p 0 -S mc -X stuff \"text\":\"§b§l§n再起動§rを開始します\"}
screen -p 0 -S mc -X eval 'stuff "\015"'

screen -p 0 -s mc -X eval 'stuff "playsound ui.toast.challenge_complete master @a\015"'

sleep 5

screen -p 0 -S mc -X eval 'stuff "title @a title {"'
screen -p 0 -S mc -X stuff \"text\":\"§b§l§n再起動§rは§e§l§n約5分§rで終了します。\"}
screen -p 0 -S mc -X eval 'stuff "\015"'

sleep 5
```
40代おっさんURLを勉強してみる。

#40代おっさんURLを勉強してみる。
##URLとは

Webページの場所を示す「アドレス（住所）」のことです。
すべて固有のものになっています。

例）GoogleのトップページはこのようなURLになっています。
https://www.google.co.jp/

##URLの形式

例えば次のようなURLがあります。

`https://www.koichi.com`

###https
これは通信の手段を表しています。
簡単に言いますと
サーバーとブラウザ間のデータのやりとりは、「HTTP(S)」というルールに従って行いましょう。
と決めて通信を行っていると言うことです。

###www
これはホスト名を表しておりWWWの意味は下記になります。
WWWはWorld Wide Web（ワールド・ワイド・ウェブ）の略称です。
これもわかりづらいですよね・・・
これも調べましたがつまりテキストとテキストをつなげる仕組み（俗にハイパーテキストと言う）これを表しているとのことです。

###koichi.com
これはドメイン名と言います。
ドメイン名はインナーネット上の「住所」つまりこれがURLの固有のものであることを示しています。
koichi.comは二つの意味を表しています。
####一つはcomです。
みなさんもよく見たことがあると思いますが基本は商業用を表します。ほかにjpなども見かけますがこれは日本を表しています。
####もう一つはkoichiです。
基本これが固有のものを表すしています。comの中のkoichiをさしています。

##ドメインはどこで手に入れるの？
ドメインは基本レジストリ（日本では日本レジストリサービス）（最高機関はICANN）が管理しており、そこから卸してもらっているレジストラが一般に販売しております。（リセラーと言うのもあり、こちらはドメイン登録代行業者のようです）

##ドメインを買うとすぐに使えるの？
買うだけではだめでIPアドレスと紐づけることで使用できます。

###IPアドレスとは？
スマホやPCなど、ネットワーク上の機器に割り当てられるインターネット上の住所のような存在です。
あれ？？
URLも住所なのでは？
と思いましたよね・・・
つまり本当はIPアドレスが住所の役割であり、それをわかりやすくするためにドメインで指定してURL決めているのです。
これを名前解決と俗に言います。

#最後に
本記事は初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。
JDLA E資格に関する私の投稿記事リスト

#はじめに
この記事は、__JDLA E資格__について、私がQiitaに投稿した記事をリスト化したものです。
詳細内容については、各記事をご覧ください。
必要に応じて更新します。

【2021年3月11日追記】
JDLA E資格2021#1に合格していました。


#E資格試験全体
[私の投稿方針とE資格][link-1]
[link-1]:https://qiita.com/fridericusgauss/items/2c169387eacf21a915ab

[E資格試験の試験形式や受験までの流れ][link-2]
[link-2]:https://qiita.com/fridericusgauss/items/2427c9240591071109f8

[E資格試験の合格ラインと合格のための戦略][link-3]
[link-3]:https://qiita.com/fridericusgauss/items/98497e96c03d99cba327

[E資格試験の出題傾向分析][link-4]
[link-4]:https://qiita.com/fridericusgauss/items/c15ead8a731a4ba46855

[E資格試験2021#1 合格体験記][link-5]
[link-5]:https://qiita.com/fridericusgauss/items/b4a5bbbacd6cee528a27

#E資格試験の応用数学パート解説
###線形代数
[固有値分解・特異値分解][link-6]
[link-6]:https://qiita.com/fridericusgauss/items/89b9cb4a8e6b7cbd4798

[L^pノルム・距離関数（mathlog）][link-7]
[link-7]:https://mathlog.info/articles/1844

[L^pノルム・距離関数][link-8]
[link-8]:https://qiita.com/fridericusgauss/items/f3d8575abfe7f67f1d7d

###確率・統計
[期待値・分散][link-9]
[link-9]:https://qiita.com/fridericusgauss/items/ab36d7cf91093d284ba0

[確率分布][link-10]
[link-10]:https://qiita.com/fridericusgauss/items/14bbcdc0423fc39067c2

[最尤推定法][link-11]
[link-11]:https://qiita.com/fridericusgauss/items/1232149cf2cb680e4ab0

[ベイズの定理][link-12]
[link-12]:https://qiita.com/fridericusgauss/items/adb7e8487a980205ff5b

###情報理論
[情報エントロピー][link-13]
[link-13]:https://qiita.com/fridericusgauss/items/0716ffd297c4f7b2dca7

#E資格試験の機械学習パート解説
###教師あり学習
[線形回帰][link-14]
[link-14]:https://qiita.com/fridericusgauss/items/42b5cd0bf8ea4b79b86a

[基底展開法に基づく非線形回帰][link-15]
[link-15]:https://qiita.com/fridericusgauss/items/3052ba024521f50bd666

[カーネル回帰][link-16]
[link-16]:https://qiita.com/fridericusgauss/items/62f79879d8b95ff12d51

[ロジスティック回帰][link-17]
[link-17]:https://qiita.com/fridericusgauss/items/35fd7b274c5e131502e3

###教師なし学習
執筆中。

###強化学習
[強化学習の基礎とアルゴリズム分類][link-18]
[link-18]:https://qiita.com/fridericusgauss/items/baf720e21f6811bd8908

[強化学習の価値関数とベルマン方程式][link-19]
[link-19]:https://qiita.com/fridericusgauss/items/a2b868490eb809b19872

[強化学習の価値ベースのアルゴリズム（Q学習とSarsa）][link-20]
[link-20]:https://qiita.com/fridericusgauss/items/f87984d4bcd0e143fef6

[強化学習の方策ベースのアルゴリズム（方策勾配法）][link-21]
[link-21]:https://qiita.com/fridericusgauss/items/aa5215c29646963bda29


#E資格試験の深層学習パート解説
###深層学習の概要
執筆中。

###深層学習の順伝播と逆伝播
[機械学習モデルの計算グラフ][link-22]
[link-22]:https://qiita.com/fridericusgauss/items/6f7a8872f7d6f5703361

###深層学習における最適化
執筆中。

###畳み込みニューラルネットワーク(CNN)
[画像認識タスクの分類とCNNモデルの対応関係][link-23]
[link-23]:https://qiita.com/fridericusgauss/items/885d068f3061137b73c5

###再帰型ニューラルネットワーク(RNN)
執筆中。

###深層学習を用いた自然言語処理
執筆中。

###深層学習を用いた生成モデル
執筆中。

###深層強化学習
執筆中。

#E資格試験の開発・運用環境パート解説
執筆中。

#その他
私が作成しました。
[wikipedia: E資格][link-100]
[link-100]:https://ja.m.wikipedia.org/wiki/E%E8%B3%87%E6%A0%BC

【2021年3月16日追記】
Qiita投稿記事の中で、3つの記事が閲覧数1000件超えました。感謝です。

【2021年4月4日追記】
Qiita投稿記事の中で、4つの記事が閲覧数1000件超えました。感謝です。
React メモ

#React セットアップ

```terminal
npx create-react-app app_name
```

#Material-UI

app_nameのpackage.jsonに、
・@material-ui/core
・@material-ui/icons
・@material-ui/system
が追加される

```terminal:terminal
npm install --save @material-ui/core @material-ui/icons @material-ui/system
```

フォントを正しく反映できるように下記を追加

```index.html
<!-- フォント -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
<!-- アイコン -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
```

#プロジェクトを実行
npm startとは、npmコマンドの1つで、npmを使用してファイルやプロジェクトを実行することができます。
package.json の scripts.start に指定された内容を実行することができます。

```terminal:terminal
npm start
```

#画像の表示

①importして表示する方法

```react:jsx
import React from 'react';
import logo from './logo.png'; // Tell Webpack this JS file uses this image

console.log(logo); // /logo.84287d09.png

function Header() {
  // Import result is the URL of your image
  return <img src={logo} alt=
"Logo" />;
}

export default Header;
```

②静的ファイルを直接参照する方法

```react:jsx
import React from 'react';

function Header() {
  return <img src={`${process.env.PUBLIC_URL}/logo.png`} alt="Logo" />;
}

export default Header;
```

#ReactRouter

①react routerのインストール
※Reactが入っているディレクトリで実行する

```terminal:terminal
npm i -S react-router-dom
```

②App.jsでreact-routerのインポート

```js:App.js
import { BrowserRouter, Router, Link } from "react-router-dom";
```

③App.jsにトップページを設定するコードを書き込む

```js:App.js
const App = () => (
  <BrowserRouter>
    <div>
      <Route exact path="/" component={Home} />
    </div>
  </BrowserRouter>
)

const Home = () => {
  return (
    <div>
      <h1>Welcome</h1>
    </div>
  )
}
```

#Material UI KIT セットアップ

①webpackのインストール

```
npm i -D webpack webpack-cli
```

②webpackのコンフィグファイルを作成します。
ここでは、親ファイルをwebpack.config.jsとし、詳細はdevelopment.jsを読ませることにします。
```
touch webpack.config.js development.js
```

③設定ファイルには以下のように記述します。

```webpack.config.js
webpack.config.js
require('@babel/register'); // development.jsでES6を使えるようにする
module.exports = require('./development');
```

```development.js
import path from 'path'

const src  = path.resolve(__dirname, 'src')
const dist = path.resolve(__dirname, 'dist')

export default {
  mode: 'development',
  entry: src + '/index.jsx',

  output: {
    path: dist,
    filename: 'bundle.js'
  },

  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      }
    ]
  },

  resolve: {
    extensions: ['.js', '.jsx']
  },

  plugins: []
}
```

#PIDの消し方

```
$ ps l
$ kill ID名
```
xrdp で GNOME Keyring が動かない

Ubuntu 20.04 に xrdp を導入し RDP接続してから ターミナルで ssh を実行するたびに秘密鍵のパスフレーズを入力されるようになった。パスフレーズはGNOME Keyringに登録しているので自動的に解決されるようにしたいので調査した。

xrdp 用のPAM設定を変更するとGNOME Keyringが動いたので設定内容を記載します。


```/etc/pam.d/xrdp-sesman
#%PAM-1.0
@include common-auth
auth     optional        pam_gnome_keyring.so
@include common-account
@include common-session
session  optional        pam_gnome_keyring.so        auto_start
@include common-password
password optional        pam_gnome_keyring.so
```

```$HOME/.xinputrc 
eval $(/usr/bin/gnome-keyring-daemon --start --components=pkcs11,secrets,ssh)
export SSH_AUTH_SOCK
```

設定すると GHOME Keyring のパスワード入力画面が表示されたのでパスワードを入力する。※GNOME Keyringのデフォルトパスワードをログインパスワードと同じものを設定していると入力画面は表示されないかもしれない。入力後はssh実行時にパスフレーズ入力を要求されなくなった。

参考記事
1. [Ubuntu Weekly Recipe 第621回　Ubuntu 20.04 LTSでxrdpを使用する](https://gihyo.jp/admin/serial/01/ubuntu-recipe/0621)
2. [Gnome Keyringの使い方](https://qiita.com/onokatio/items/9ca0305e35243cca6119)