OmniAICreator/Qiita-1.07M huggingface dataset:
2021_8.1.0.1　備忘録:Snortインストール編

概要：
Snortとは、OSS(オープンソース)のネットワーク型IDS(侵入システム:Intrusion Detection System)として有名なソフトウェアです。商用版とGPL(GUN Public License)で配布されているフリー版があり、今回はフリー版を使用します。多くのLinuxディストリビューションをはじめ、WindowsやUnixなど様々なOSで使用できます。不正アクセスなどを検知するために、「シグネチャ」(言いにくい)と呼ばれるルールを設定します。シグネチャは、独自のものを作成する(local.rules)ことが可能です。シグネチャは、ルールヘッダとルールバディという2つの部分からできております。

環境：
OS CentOS　Linux release 8.3.2011
アーキテクチャ x86_64
kernelバージョン　4.18.0-240.10.1.el8_3.x86_64

作業：
下記のサイトから最新のSnortを調べてください。
https://www.snort.org/downloads/
今回は、「snort-2.9.18-1.centos8.x86_64.rpm」を使用します。

```rb
# yum install https://www.snort.org/downloads/snort/snort-2.9.18-1.centos8.x86_64.rpm
```
下記のエラーが発生したらepel導入後、「daq」をインストールしてください。
![Snortエラー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1933632/671adca8-29a5-73a6-e4a7-67eb53b73143.png)

・epelの導入

```rb
# yum install epel-release
```
下記のコマンドは、デフォルトにしないためのコマンドなので必須ではないです。
※sedコマンドでenabled=1→enabled=0に置換しております。

```rb
# sed -i 's/enabled=1/enabled=0/g' /etc/yum.repos.d/epel.repo
```
・daqのインストール

```rb
# yum --enablerepo=epel install daq
```
再度「snort-2.9.18-1.centos8.x86_64.rpm」をインストールして完了です！！！！！
![Snort完了.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1933632/e6cc483f-5cb7-a186-00d6-957018b0975d.png)

起動：
snortdサービス起動させます。

```rb
# systemctl start snortd
```
結果です。
![snortd起動結果.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1933632/ad5b8d6c-921a-1513-5cc7-e9f1ec30e601.png)
libdnet.1が無いらしいです。
libdnetをインストールします。

```rb
# yum install libdnet
```

シンボリックリンク作成します。

```rb
# ln -s /usr/lib64/libdnet.so.1.0.1 /usr/lib64/libdnet.1
```

参考サイト：
https://acind.hatenablog.jp/entry/2020/06/16/110106
https://ex1.m-yabe.com/archives/4906
https://www.alprovs.com/wordpress/?p=655

駄文：
インストールは成功しますが、シグネチャを入れたりしてこの後も学習が必要ですね。一応、これで起動はできますが、まだまだ設定が必要となります。更新はするつもりですので、ご指摘やご感想などをいただければ幸いです。ヤル気が出るので。ではでは。
7-Elasticsearchのインストール及び設定　ビルトインアカウントのパスワード変更

過去にはてなブログへ投稿したものになります

# はじめに
前回でElasticsearchの起動ができたので、これからビルトインアカウントのパスワードを変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47012/aa64c008-cdb0-fdb4-52cc-d55e186cc329.png)

作業のポイント

- この手順は　「クラスタで1回｣　だけ実施すれば良いです。
- 事前にElasticsearchを起動しておく必要があります。
- Configの「xpack.security.elabled」が「true」で無ければ設定ができません
- 実行するコマンドがデフォルトのポート(9200)に対してAPIを裏で発行しているようです。
そのため、RHEL#3で作業を実施します。

# 実施手順

以下のコマンドを実行します。 各パスワードは任意のものを設定してください。
logstash を使用していませんが、気にせずパスワードを設定して大丈夫です。

```
# /usr/share/elasticsearch/bin/x-pack/setup-passwords interactive
Initiating the setup of passwords for reserved users elastic,kibana,logstash_system.
You will be prompted to enter passwords as the process progresses.
Please confirm that you would like to continue [y/N] y
Enter password for [elastic]:パスワードを入力
Reenter password for [elastic]:パスワードを入力
Enter password for [kibana]:パスワードを入力
Reenter password for [kibana]:パスワードを入力
Enter password for [logstash_system]:パスワードを入力
Reenter password for [logstash_system]:パスワードを入力
Changed password for user [kibana]
Changed password for user [logstash_system]
Changed password for user [elastic]
```

# 確認方法（クラスタの状態確認をするAPIを発行）
セキュリティが有効の場合は、Elasticsearchに対してAPIを発行する際にID/PASを入力必要があります。
上述の手順でパスワードの設定をしましたので、APIを発行してみます。

設定と同様にRHEL#3に対してAPIを発行します。(#4、#5でも大丈夫です)
「-u」オプションの後にユーザを指定します。

```
curl -XGET -u elastic http://192.168.0.3:9200/_cluster/health?pretty
<<パスワードを求められたら入力>>
{
  "cluster_name" : "クラスタ名",  <===== 設定したクラスタ名か確認します
  "status" : "green",  <============= 「green」が正常です。それ以外は何かがおかしいので要調査です
  "timed_out" : false,
  "number_of_nodes" : 8, <========== Master及びDataノードの総数のはずです（手元に環境が無く自信なし）
  "number_of_data_nodes" : 5, <====== データノードが設定した数かどうかを確認します。
  "active_primary_shards" : 5, <======= データを投入すると数が変わるので、あまり気にしていないです
  "active_shards" : 10,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0, <========= shardのデータが破損した時の数です。
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}
```

# 「.security」について
下記のAPIを発行するとインデックスの一覧が表示されます。 現段階だと「.security」というインデックスがあるはずです。
こちらに上記で設定したビルトインアカウントのパスワードが入っているようです。

なので、全インデックスの削除コマンドを実行すると.securityも削除され、APIの認証が通らなくなります。
(筆者が実際にやってしまった） 誤って消してしまった場合も、上記の手順で再度パスワードの設定ができます。（検証済）
また、Configの「action.destructive_requires_name」に「true」を設定することで、インデックス名を指定しないと削除ができなくなりますので、この定義は設定した方が良いです。

```
curl -XGET -u elastic http://192.168.0.3:9200/_aliases?pretty
<<パスワードを求められたら入力>>
～実行結果は手元にないです・・・～
```
Macターミナルコマンドでパスワードを変更する。

Macのターミナルコマンドでパスワードを変更する方法を紹介します。
ターミナル画面で、`passwd`を入力することで、変更することができます。

```
$ passwd
Changing password for xxxx.
Old Password:
New Password:
Retype New Password:
```

`passwd`と入力すると、

- 現在のパスワード
- 新しいパスワード
- 新しいパスワードの再入力

を求められるので、入力します。

システム環境設定を使わずに変更できるので、頻繁に変更する方には便利です。
【Django】管理サイトでmodelのURLFieldをリンクで表示したい

## 目的
- ユーザーがメッセージやファイルなどを投稿するサービスを開発中
- 投稿内容がポリシーに違反している場合、他ユーザーが報告できる機能を作成
- 報告を受けた場合、Reportというモデルに報告内容を登録
- 報告内容には、違反とされる投稿内容のURLを含んでいるので、管理サイトから簡単に遷移したい

## 参考資料
[Django 管理サイトをカスタマイズする前に教えてほしかったこと](https://speakerdeck.com/akiyoko/how-to-customize-admin-djangocon-jp-2021)
※とても分かりやすかったです。ありがとうございます。

## コード
```python:project/report/models.py
from djnago.db import models
from django.contrib import admin
from django.utils.html import format_html

class Report(BaseModel):
    url = model.URLField(null=False, verbose_name='違反があったURL')

    class Meta:
        db_table = 'report'

    @admin.display
    def url_link(self):
        """管理サイト URLリンク表示用"""
        return format_html(
            '<a href="{}" target="_blank" rel="noopener noreferrer">{}</a>',
            self.url,
            self.url
        )
```

```python:project/report/admin.py
from django.contrib import admin

from .models import Report

class ReportAdmin(admin.ModelAdmin):
    # 管理サイトで表示するフィールドを定義
    # modelで定義した"def url_link"を指定することで、URLをaタグで得られる
    list_display = ('url_link',)


# ReportとReportAdminを紐付ける
admin.site.register(Report, ReportAdmin)
```


これで管理サイト上でURLをリンクとして表示できました。
Answers　での実績


# 2022年04月10日の結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/16a4bed3-e1e8-2cd0-6ecf-b2208aa54173.png)


# 2022年02月15日の結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/752495d8-cdbf-bb17-2477-55d899b1f957.png)



# 2021年10月21の結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/5344cbfe-9d91-0627-9909-235afc909737.png)

# 10000回答達成

![20211006-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/5306875a-a3b6-99ac-3813-cb89fed0cdb5.png)

# 2021年6月12日の結果
Answersの総合順位(?)は６月に入って残念ながら2位に落ちました。
週間順位は久しぶりに1位になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/2eb42094-b998-54b8-8f4a-9e6ae4a0d3e4.png)



# 2021年5月3日の結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b0c9f38b-eeb9-d5a0-920c-aa3d14f76b3b.png)


# 2021年4月30日の結果
![20210430-1b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/fff13c07-0da4-1a83-7e11-273653aea13a.png)
初の１位、しかし１日限りだろう。


# 2021年1月の結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/badd144f-bf7b-15c7-60e1-a3e9d3a96edc.png)
[Windows] エラーメッセージをローカルで検索する

# Microsoft Error Lookup Tool

```
Err_6.4.5.exe <error code>

```

参考；
* https://docs.microsoft.com/ja-jp/windows/win32/debug/system-error-code-lookup-tool
* https://atmarkit.itmedia.co.jp/fwin2k/win2ktips/644err/err.html



参考：http://pocketstudio.jp/log3/2012/02/13/change_language_and_chcp/

# Windowsネットワークメッセージを確認

```
net helpmsg <error code>

```


# Cmdプロンプトの言語設定を変更

セッション単位での設定

```

# 英語に設定
chcp 437

# 日本語に設定
chcp 932

```
WindowsとUbuntuでGitHubをSSHで使う。

GitHubをSSHで使う方法を検索すると、さまざまな環境のいろいろな方法が出てきて、どれが正しいのかわからない。（正確にはどれも正しいのだが、自分の環境で実現可能かどうかがわからない。）そこで、最もシンプルで一般的だと思う組み合わせを実際に試してみた結果を記す。

**【注意】** `eval "$(ssh-agent -s)"` するとか、`ssh-add` するとか、OpenSSH クライアント/サーバーをインストールするなどの方法もあるが、Git Bashのプロセス限定だったり、個人環境に依存することもある。少なくともここで紹介する方法は、2台のWindows 10とUbuntu Desktop 20.04で動作を確認している。



## Windowsだけの準備

Windows 10の中で眠っているSSH Agentを起動する。
（参考：[栄諧情報システム株式会社「Windows10 の OpenSSH で ssh-add をすると警告が出て鍵を登録できない」](https://eikai.co.jp/2020/10/2218/)）

1. スタートメニュー（右クリック）から「コンピューターの管理」→「サービスとアプリケーション」→「サービス」→「OpenSSH Authentication Agent」のダイアログを開く。
1. スタートアップの種類を「自動」に変更する。
1. サービスの状態を「開始」に変更する。

![Windows SSH Agent.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51783/e22afd77-d91f-9cb1-5f8c-7dae4af0c7ee.png)

## SSH Keyの作成

SSHで使用する公開鍵を作る。
（参考：[Qiita GakuNaitou「gitでPlease make sure you have the correct access rights and the repository exists. が出た時の対処法」](https://qiita.com/GakuNaitou/items/81dbbd3ea6211af71648)）

1. WindowsはGit Bashを、Ubuntu(Linux)ならbash（端末）を起動する。
1. *~/.ssh* に移動する。ファイルは存在しない方が望ましい。
1. *known_hosts* ファイルが存在する場合、*github* の項目があったら消しておく。
1. `ssh-keygen -t rsa -C ""` を実行して公開鍵を作成する。パスフレーズは入力しない。
1. *id_rsa*（秘密鍵）と *id_rsa.pub*（公開鍵）が作成されていることを確認する。
1. *config* ファイルを以下のとおりに作成する。

```text
Host github
  HostName github.com
  IdentityFile ~/.ssh/id_rsa
  User git
```

## GitHubの設定

公開鍵をGitHubに登録する。

1. GitHubにサインインする。
1. 右上メニューから「Settings」→「SSH and GPG keys」の画面に移動して、ボタン「New SSH key」から登録画面を開く。
1. 「Title」にはパソコン名などを入力、「Key」には *id_rsa.pub*（公開鍵）のテキストを貼り付ける。最後にボタン「Add SSH Key」で登録する。

![SSH and GPG keys.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51783/36964320-60c1-7a1d-fd39-d8280233e1a9.png)

## Gitの動作確認

ここまでで設定のすべてが完了した。もしも期待した動作をしない場合、手順を間違えているか、環境に問題があると思われる。

1. bashで `ssh git@github.com` を実行して接続確認をする。
1. *~/.ssh/known_hosts* ファイルが作成されて、*github* の項目が追加される。
1. 適当なローカルリポジトリに移動して、`git fetch` とか `git pull` してみる。
1. 以降、どのシェルでgitコマンドを打っても、Visual Studio CodeのGit Graphでfetchしても、何も聞かれずに済む。

![SSH Test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51783/0680aae8-f109-2b94-40b2-40d6b781381b.png)

以上
【Ruby on Rails】SNSシェアボタンを実装する方法


#対象者

* SNSシェアボタンを実装予定の方


#目的

* SNSシェアボタンを実装して共有できるように設定する

#実際の手順と実例
###1.前提

Articleモデル使用しています。


###2.'social-share-button'を導入

```Gemfile
gem 'social-share-button'
```

導入後、**bundle install**を実行

その後、configにsocial_share_btn.rbファイルを作成します。

```terminal
rails g sosial_share_button:install
```
これを実行することで、表示したいSNSボタンを設定する事ができます。

````config/initialize/sosial_share_button.rb
SocialShareButton.configure do |config|
  config.allow_sites = %w(twitter facebook)
end
````
（）内に自分の入れたいアプリを入力していく
今回はTwitterとFacebookを実装します。


###3.assetファイルの設定

application.scssにsosial_share_buttonが使えるように設定します。
 
````assets/stylesheets/application.scss
 *= require social-share-button  #追記
 *= require_tree .
 *= require_self
 */
@import "social-share-button"; #追記
```

⚠順番に注意してください


続いて、jsファイルも設定していきます。

````assets/javascripts/application.js
//= require turbolinks
//= require_tree .
//= require social-share-button #追記
````

### 4. Viewでの設定

````app/view/articles/show.html.erb
<%= social_share_button_tag(@article.title) %>
````

* @articleはコントローラーで**Article.find(params[:id])**を定義しています。
* titleはArticleのカラムです。ご自身のモデルに合わせて設定してください。投稿した際にタイトルが表示されます。


### 補足

scssファイルでサイズや配置を変更します。

````application.scss
$size: 28px;
.social-share-button {
    display: flex;
    flex-direction: column;
    padding-left: 50px;
  .ssb-icon {
    background-size: $size $size;
    height: $size;
    width: $size;
    margin: 10px 0;
  }
}
````

私の場合縦並びにしたかったので
    display: flex;
    flex-direction: column;
を設定しています。

これで実装完了です！


####投稿者コメント

少し前にSNSシェアボタンを設置して、簡単だったけど、どんな手順で実装したんだっけと忘れてしまったのでアウトプットしてみました。


####My Profile
プログラミング学習歴３ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。
AWS AppSyncのAPIをAmazon Cognito ユーザープールで保護する

先日開催した[ハンズオンイベント](https://kintonecafe-hamamatsu.connpass.com/event/222083/)のフォローアップ記事です。

ハンズオンのコードではAPIの保護についてAPI-Keyを利用していました。開発時やお試しの時には簡単で良いのですが、本番環境ではAPI-Keyが丸見えになるので別の方法が必要になります。その際の回答の1つです。

基本的には下記の通りになります。
https://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/security-authz.html

今回はCognito認証を追加します。
ハンズオンのコードを使ってどこに何を設定すれば良いかを記載します。


# 認証の追加
今回、API-Keyによる認証はそのままにして認証を追加します。

設定から「New」を選択
![スクリーンショット 2021-08-25 7.27.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/0b8877ff-dfd6-5895-e797-3d85a592a509.png)

認証モードとリージョン、ユーザープールを選択します。
![スクリーンショット 2021-08-25 7.30.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/ced9611b-25de-bc2d-fefc-4fa8e7b0b407.png)

※リージョンはハンズオンで作成したAmplifyアプリのリージョンを選択。
※ユーザープールはAmplifyのバックエンドの設定を確認して同じものを選択します。

![スクリーンショット 2021-08-25 7.34.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214523/1a3a8d34-f8bb-e2e1-567a-e242c516bae4.png)

# Schema
AppSyncのGraphQLスキーマに下記を追加します。

`@aws_cognito_user_pools`

```graphql
type Mutation @aws_cognito_user_pools
@aws_api_key {
	addNote(record: PostNote): PostRecord
	deleteNote(ids: [String]): Boolean
	updateNote(id: String, record: PutNote): PutRecord
}

type Query @aws_cognito_user_pools
@aws_api_key {
	listNotesForUser(owner: String): Records
}
```
【初心者向け】MySQL　CRUDとは

#はじめに#
　CRUDというのはシステムのデータを操作するのに必要な主要機能のことです。
初めて聞いたよーという方や、あんまりよく分かってないよーという方に向けて、ざっくり概念を知っていただけるように書いていきたいと思います。

誤り等ありましたらご指摘いただきますと幸いです。

それでは参りましょう！


#CRUDとは#
　CRUDとはデータを操作するのに必要な機能
・Create（生成）
・Read（読み取り）
・Update（更新）
・Delete（削除）
の頭文字を取ったものです。

データベースを用いたアプリケーションというのは大体この4つの機能で成り立っています。


##CREATE##
　実際にSQLでどんな文を書くのか見てみましょう。

```sql:create.sql
INSERT INTO products (id, name, price, stock) VALUES(1, 'りんご', 200, 10);
```

　ここではデータの挿入が行われます。INSERT文を用いることでデータを挿入することが出来ます。
　productsはテーブル名になります。
　また、（）の中にはカラム名が入ります。ここでは、id・name・price・stockという4つのカラムが存在しており、カンマ区切りで書かれています。
　VALUES後の（）には実際に挿入されるデータが入ります。また、先ほど記入したカラム名とカンマ区切りで対応しており、それぞれに対応した値が挿入されます。ここではidには1、nameにはりんご、priceには200、stockには10が入ります。


##READ##

```sql:read.sql
SELECT * FROM products; 
```
　ここではデータの読み取りを行います。SELECT文でデータの取り出しが可能です。
＊というのはデータを全て取ってくるよーという意味です。カラム名を指定することもできます。その場合は、指定したカラム名のデータのみ取ってきます。
　FROMの後ろにはテーブル名が入ります。この場合だと、productsというテーブルから全てのデータを取ってきますので、id=1、name=りんご、price=200、stock=10というデータを取得することが出来ます。
　取得されたデータは配列に格納され、カラム名はキー、値はバリューとした連想配列になります。


##UPDATE##
```sql:update.sql
UPDATE products SET price=220 WHERE id=1; 
```

　ここではデータの更新が行われます。UPDATEの後には更新したいテーブル名を入れます。
SETの後に更新したい値とカラム名を＝でつなぎます。今回はpriceを200から220に変更したいケースを想定しています。
　WHERE以下では更新したい値の条件を指定できます。今回はidが1のデータを指定しています。これを指定しないと全てのデータのpriceが220に更新されてしまいますので注意してください！


##DELETE##
```sql:delete.sql
DELETE FROM products WHERE id=1; 
```
　ここではデータの削除が行われます。DELETE FROMの後にテーブル名を指定し、その後にさらに条件分を付け足します。今回はid=1のデータを削除します。先程同様、WHERE句を指定しないとデータが全て削除されてしまいますので要注意です！



##まとめ##
　CRUDとは何か、そしてそれぞれの具体的な例についてみていきました。どんなアプリケーションでも基本はこの4つの機能から成り立っています。しっかり使いこなせるように学習していきましょう！
HTMLの文法について

## HTMLとは
HyperText Markup Languageの略。
ウェブサイトに表示される情報を記載する言語です。
〇〇.htmlという名前のファイルに記述します。

## 要素
HTMLにおける要素は、HTMLを構成するために必要な成分です。
いくつもの要素が積み重なって、HTMLは構成されます。

```test.html
<body>
  <h1>
    お疲れ様です
  </h1>
</body>
```

この\< >...\</ >一つひとつをHTMLの要素と呼び、それぞれ役割をもっています。

## タグ
HTMLにおける要素のかたまりを示す記述です。
タグには、要素の始まりを示す開始タグと、終わりを示す終了タグがあります。
なお、終了タグが無い要素も存在します。

```test.html
<body> ←開始タグ
</body> ←終了タグ
```

## head要素
ウェブサイトの情報や、装飾用のCSSファイルの情報を記載する部分です。
ここに記述した情報は画面上に表示されません。

## body要素
画面上に表示したい情報を記載する部分です。
ブラウザ上に表示されている情報は、body要素の中に記述されたものです。

## DOCTYPE (読み方：ドックタイプ)
DOCTYPEは「ドキュメントタイプ」の略で、この文章がHTML文章であることを宣言する要素です。終了タグはありません。
実際に記述する場合は、<!DOCTYPE HTML>のようにします。この要素を記述しないと、レイアウトが崩れ、正しく表示がされない場合があります。

## html要素
HTML文章の始まりと終わりを示す要素です。こちらもHTMLを書く際に必要です。

```test.html
<!DOCTYPE HTML>
<html>
  <head>
  </head>
  <body>
  </body>
</html>
```

## head要素について

### meta要素 (読み方：メタ要素)
HTML文章に関する情報を指定する時に使用します。終了タグはありません。charset=はmeta要素の属性です。

### 属性
属性は、要素に情報を付け加える役割を持ちます。属性のあとには属性値が続きます。

### 属性値
どのような属性なのかを示す値を属性値と呼びます。

```test.html
<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">
    ↑meta要素。charsetが属性で、UTF-8が属性値。
~省略~
```

### charset属性 (読み方：キャラセット属性)
メタ要素にて、どのような文字コードを用いるか示すことができる属性です。「キャラセット」と読むことが多いです。今回は、属性値をUTF-8としました。

※UTF-8とは、世界的にも最もポピュラーな文字コードで、Unicode用の符号化方式の1つです。ASCIIで定義している文字を、Unicodeでそのまま使用することを目的として制定しています。

### title要素
ウェブサイトのタイトルを指定する要素です。
title要素内にタイトルを記述してもウェブサイトの画面上には表示されません。
Googleでの検索結果や、ブラウザのタブに表示するタイトルとして使用されます。

```test.html
<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">
    <title>ウェブサイトのタイトル</title>
  </head>
  <body>
~省略~
```

## body要素について

### h1 〜 h6要素
hはHeadingの略で、hから始まるh1/h2/h3/h4/h5/h6の要素は文章の見出しを作るための要素です。
見出し要素は、\<h1>から\<h6>まで存在します。
h1〜h6のタグに囲まれたテキストは見出しとして強調され、\<h1>から順に文字の太さと大きさが小さくなります。

### p要素
pはParagraphの略で、文章の段落を表す要素です。
\<p>...\</p>で囲むとひとかたまりの段落として認識されます。
Webページ内では、見出しを除くテキストのほとんどが、このp要素を使って作られます。

### br要素
brはLine Breakの略で、テキストを改行するための要素です。br要素をテキストの中で用いることで、改行ができます。br要素は終了タグが不要です。

### b要素
bはBoldの略で、文字でを太くする要素です。
\<b>...\</b>で囲まれている部分だけ太字になります。

### a要素
aはAnchorの略で\<a>...\</a>で囲ったテキストをリンクにすることができます。
a要素をクリックすると特定のページに移動します。aタグのhref属性に、移動させたいページのURLを指定します。

### href属性 (読み方：エイチレフ属性)
hrefはHyper Referenceの略で、href属性でリンクの移動先を指定します。
属性値としてURLや移動させたいページのHTMLファイルが置いてあるフォルダの場所を指定することで、特定のページへのリンクが作成できます。

```test.html
<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">
    <title>ウェブサイトのタイトル</title>
  </head>
  <body>
    <h1>
      これは見出しです
    </h1>
    <p>
      1つ目の段落です
    </p>
    <p>
      2つ目の段落です
    </p>
    <p>
      3つ目の段落です。<b>この部分は太字になります。</b>
    </p>
　　　　　　　　　　<a href="https://www.google.com/">クリックすると、Googleへ移動します。</a>
  </body>
</html>
```
【JavaScript】変数と宣言

# 概要
JavaScriptを学習、理解を深めるため「[JavaScript Primer 迷わないための入門書](https://jsprimer.net/)」を読み、
理解した内容等を記載していく。

[JavaScript入門一覧](https://qiita.com/andota05/items/22fae452225b785fd405)に他の記事をまとめています。

# この記事で理解できること
* 変数宣言に使用できるキーワード
* 各宣言キーワードの特徴
* 変数名のルール(命名規則)

# 変数と宣言
JavaScriptには以下３つの変数宣言キーワードが存在する。

* const(`ES2015〜`)
* let(`ES2015〜`)
* var

# 「const」「let」 および「var」について
* varは古くから変数宣言に用いられていたキーワードで、`意図しない動作`を生み出しやすいことが懸念されていた。
* `ES2015`からconst、letが追加されたことで`varが抱えていた問題を回避`できるようになった。
* 既にvarで書かれたコードの動作を考慮し、`var自体の変更・改善`はされていない。

> **ECMAScript**
> JavaScriptの動作を決めている仕様の名称
> 2015年にECMAScript 2015(ES2015)という大きなアップデートが行われた仕様が公開された
> ECMAScriptは毎年更新され、構文や機能が追加されている

# 各宣言キーワードと特徴について
各キーワードの宣言方法および、特徴を記載していく。

## const

* `初期値`は必須。
* constで宣言された変数には`再代入`できない。
* `同じ変数名を複数定義`しようとすると構文エラーとなる。
* 変数に対して`値を再代入`する必要がない場合は、constが推奨されている。

```js
// 定義方法
const 変数名 = 初期値;
```
```js
// 例：titleという変数を宣言し、初期値を設定
const title = "JavaScript入門"
```

# let

* 初期値なしの変数宣言が可能(値が未定義ということを表す`undefined`という値で初期化される)
* `同じ変数名を複数定義`しようとすると構文エラーとなる。
* 変数が参照する値を変化させたい場合など、`変数への再代入`が必要な場合はletを利用する(`例：ループなどの反復処理`)

```js
// 定義方法(初期値なし、あり)
let 変数名;
let 変数名 = 初期値;
```
```js
// 例：初期値なし
let title;

// 例：titleという変数を宣言し、初期値を設定
let title = "JavaScript入門";

// 「JavaScript入門」から「JavaScript初級」へ値を再代入
title = "JavaScript初級";
```

# var

* 初期値なしの変数宣言が可能。(値が未定義ということを表す`undefined`という値で初期化される)
* `変数への値の再代入`が可能。
* 同じ変数名を`再定義`してもエラーにならない。

```js
// 定義方法(初期値なし、あり)
var 変数名;
var 変数名 = 初期値;
```
```js
// 例：初期値なし
var title;

// 例：titleという変数を宣言し、初期値を設定
var title = "JavaScript入門";

// 「JavaScript入門」から「JavaScript初級」へ値を再代入
var title = "JavaScript初級";
```
```js
// 例：同じ変数名で再定義
var title = "JavaScript入門";
var title = "JavaScript初級"; // 変数titleの値は「JavaScript初級」へと上書きされる

// ちなみに値を設定せず再定義した場合は「undefined」にはならず「JavaScript入門」のまま
var title = "JavaScript入門";
var title;                    // →この時点では「JavaScript入門」のまま
var title = "JavaScript初級"; // 変数titleの値は「JavaScript初級」へと上書きされる
```

# 変数名に使える名前のルール
* 変数や関数の`宣言時に付ける名前にはルールが存在する`(命名規則という表現する場合もある)
* 以下のようなルール(命名規則)が存在する。

## OKなこと
* 名前には`半角アルファベット`、`_`(アンダースコア)、`$`(ダラー)、`数字`が使用できる。
* 上記を組み合わせて使用する。

※大文字小文字は区別される

```js
const $;           // OK
const _result;     // OK
const javascript;  // OK *この二つは別の変数として区別される
const JAVASCRIPT;  // OK *この二つは別の変数として区別される
const js_2021:     // OK
```

## NGなこと
* `数字`から始まる名前にすること。
* `予約語`と同じ名前にすること(JavaScriptで用意している機能名に使用されているもの)

※ ひらがなや一部の漢字など変数名に使用できるが、全角文字が混在すると扱いにくい場合があるため非推奨

```js
const 2021_js;      // 数字からは始まる名前はNG
const let;          // 予約語(JavaScriptが用意している機能の名前)と同じはNG
const Qiitaで学習;  // OK(だが全角が混在すると扱いにくい場合があるため非推奨)
```

# 【Tips】 constは定数(不変)ではない 
* `const`キーワードの宣言された変数への`値の再代入`はできないが`不変`ではない。

```js
// 例：オブジェクトが持つ値(プロパティや、プロパティの値)の変更は可能
const taro = {name: "Taro", age: 24};
console.log(taro); // => {name: 'Taro', age: 24}

// オブジェクトtaroのnameプロパティの値を変更
taro.name = "taro";
console.log(taro); // => {name: 'taro', age: 24}

// プロパティを追加
taro.u = "プロパティuを追加しました";
console.log(taro); // => {name: 'taro', age: 24, u: 'プロパティuを追加しました'}
```
React応用 - TypeScriptをかじる1 - 超基本

### <font color="red">※一番下あたりのジェネリックス、aynsc/awaitは書きかけ</font>

# TypeScriptとは

- JavaScriptを拡張し作られた言語
- 2014年頃にMicrosoftが開発し発表
- Googleの開発で採用された
- コンパイルするとJavaScriptのコードに変換される(コンパイルが必要)


# TypeScriptの特徴

- 変数のデータ型を宣言時に決定できる
- 異なるデータ型の引数を処理できる

# 変数に型注釈をつける

型を指定して変数を宣言する。ということですね。
以下のように書きます。

```typescript
let str: string = 'あいう';
let num: number = 0;
let bln: boolean = false;
```

<font color="red">もちろん、string型に数値は代入できませんし、num型に文字列は代入できません。</font>


# any型

なんでもOK型
<font color="red">※プロジェクトの初期設定(package.jsonとか？)で許可しないような設定にしている場合あり</font>

```typescript
let anygata: any;

anygata = 123;
console.log(anygata);

anygata = 'あいうえお';
console.log(anygata);
```

# ユニオン

```typescript
let uni: 'abc' | '123' | '+++';

uni = 'abc';
console.log(uni);

uni = '123';
console.log(uni);

uni = '+++';
console.log(uni);

uni = '++++';  // ★★これは'abc' でも '123' でも '+++'ないのでコンパイルエラー
console.log(uni);
```

# Omit

```typescript
// 元の型定義
type Moto ={
    atai1: string;
    atai2: string;
    atai3: string;
    atai4: string;
}

// 元の型の初期化用
const initMoto: Moto = {
    atai1: '',
    atai2: '',
    atai3: '',
    atai4: '',
}

// 先の型（元から一部のプロパティを除く
type Saki = Omit<Moto, "atai2" | "atai4">

// 先の型で変数を定義
const saki: Saki = initMoto;

saki.atai1 = '111';
saki.atai2 = '222';  // ★コンパイルエラー
saki.atai3 = '333';
saki.atai4 = '444';  // ★コンパイルエラー
```



# ジェネリックス

`ジェネリックス`をGoogleなどで翻訳すると`汎用の`などと出てきます。

以下のような場合に使用します。


- <font color="red">使用されるまで型が決まらないような時</font>
- <font color="red">いろいろな型の値を受け入れられるように実装する時</font>


<!--
https://www.buildinsider.net/language/tsgeneric/01
https://qiita.com/k-penguin-sato/items/9baa959e8919157afcd4
-->

※ジェネリックスは他言語にもあるようですね。TypeScript固有の機能では無い。


# Promise / async / await

https://book.yyts.org/features/promise-async-await
WSL2のインストール途中でWindowsが起動しなくなった

# 結論
UEFI(BIOS)のバージョンが古かったのが原因。
アップデートしたことでWindowsが起動するようになりWSL2をインストールすることが出来た。
# 環境
|種類|バージョン|
|:-:|:-:|
|CPU|AMD Ryzen 5 3400G with Radeon Vega Graphics|
|M/B|ASRock DeskMini A300 Series|
|UEFI(BIOS)|A300M-STX P3.50T|
|OS|Windows 10 Home 21H1 19043.1165|
# 経緯
普段はIntel CPU上のWindowsでWSL2を動かしているが、検証用にAMD CPU環境も用意しようと思いWSL2をインストールすることにした。（上記環境にてインストール）
[公式ドキュメント](https://docs.microsoft.com/ja-jp/windows/wsl/ WSLドキュメント)は日本語もあるので英語はちょっとという人でも問題なくインストールできると思う。
インストール手順には簡易インストールと手動インストールがあるが簡易インストールを使用するには[Windows Insider Program](https://insider.windows.com/en-us/getting-started Windows Insider Program)に参加していないと使えないので手動インストールでインストールすることにした。

**問題は[手順 3: 仮想マシンの機能を有効にする](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#step-3---enable-virtual-machine-feature 手順3:仮想マシンの機能を有効にする)で起こった。**

仮想マシンの機能を有効にして再起動したがWindowsが起動せず最終的にトラブルシューティングが起動した。
直前の操作と言えば仮想マシンの機能を有効なのでとりあえずトラブルシューティングからBIOSを起動してSVMを無効化（AdvancedタブのCPU ConfigurationからSVM Modeを変更）して再起動してみたところ無事Windowsが起動した。
WSL2をインストールする前に一通り最新にアップデートしておいたと思ったがBIOSはアップデートしていなかったので、もう一度BIOSを起動してバージョンを確認（MainタブのUEFI Version）。

::: note
A300M-STX P3.50T
:::

[ASRockのページ](https://www.asrock.com/nettop/AMD/DeskMini%20A300%20Series/index.jp.asp#BIOS ASRock DeskMini A300 Series BIOS)で確認してみたところ最新は3.70、しかも説明には以下のように書いてある。

:::note
Follow AMD guide to support shared memory adjustment when Hyper-V is enabled
:::

Hyper-Vではないが関係がありそうなのでアップデートすることにした。
BIOSをアップデート後に再度SVMを有効化してWidnowsを起動、今度は無事再起動した。
残りのWSL2のインストール手順を実施して無事WSL2上でUbuntuが動作することを確認することが出来た。
GASでZoomのURLを生成し、定期的にSlackに投げる

# はじめに
(有料プランに入れよという話だが、)
Zoomの無料プランでは同じミーティングURLを使い続けることができないため、
URLを新規に自動生成し、Slackに定期的に投げてくれるBotを作った。


## 20210825 更新
無料プランでもミーティングURLの固定ができるっぽいので、
それをSlackの/remindで定期投稿したほうがいいかも。
固定できるのか確認中。。。

https://info-con.co.jp/tips/zoom-01-meeting-id/

# 事前準備
- Googleアカウントを用意
- Zoomアカウントを用意(あとでメールアドレスを使用します)
- Slackアカウントを用意

# ミーティングURLを発行するために、Zoomのアプリを作成
以下のZoom App Marketplaceで「**JWT**」を選択し、
指示に従ってアプリを生成したあと、表示される**API key**と**Secret**をメモる。

https://marketplace.zoom.us/develop/create


# Slackに通知するためのWebhook URLを取得
Slackに「Incoming Webhook」アプリを追加し、
指示に従ってメッセージを送信するチャネル等を選んだあと、表示される**Webhook URL**をメモる。


# GASに以下のコードを追加
```js
// SlackにミーティングURLを送信する
const sendZoomUrlToSlack = () => {
  const start_url = createMeetingRoom()
  const options = {
    method: 'POST',
    contentType: 'application/json',
    payload: JSON.stringify({text: `ミーティングはこちら:\n<${start_url}>`}),
  }
  // 上で取得したWebhook URLを記載する
  const response = UrlFetchApp.fetch('https://hooks.slack.com/services/.......Webhook URLが入る', options).getContentText()
  console.log(response)
}

// ZoomのミーティングURLを生成する
const createMeetingRoom = () => {
  const JwtToken = generateJwtToken()
  const options = {
    method: 'POST',
    contentType: 'application/json',
    headers: {Authorization: `Bearer ${JwtToken}`},
    payload: JSON.stringify(Settings),
  }
  // 上で用意したZoomアカウントのメールアドレスを記載する
  const response = UrlFetchApp.fetch('https://api.zoom.us/v2/users/Zoomアカウントのメールアドレスが入る/meetings', options).getContentText()
  const meetingInfo = JSON.parse(response)
  return meetingInfo.start_url
}

// ZoomアプリにリクエストするためのJwtTokenを生成
const generateJwtToken = () => {
  const ZOOM_API_KEY = 'ZoomのAPI keyが入る'
  const ZOOM_API_SECRET = 'ZoomのSecretが入る'
  const header = {alg: 'HS256', typ: 'JWT'}
  const payload = {iss: ZOOM_API_KEY, exp: Date.now() + 1800}

  const jsonHeader = JSON.stringify(header)
  const encodedHeader = Utilities.base64Encode(jsonHeader)
  const jsonPayload = JSON.stringify(payload)
  const encodedPayload = Utilities.base64Encode(jsonPayload)

  const signatureHMAC = Utilities.computeHmacSha256Signature(`${encodedHeader}.${encodedPayload}`, ZOOM_API_SECRET)
  const encodedSignature = Utilities.base64Encode(signatureHMAC)

  return `${encodedHeader}.${encodedPayload}.${encodedSignature}`
}

// Zoomミーティングの設定を記載
// 詳細は、https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingcreate
const Settings = {
  "type": "2",
  "timezone": "Asia/Tokyo",
  "settings": {
    "join_before_host": "true",
    "mute_upon_entry": "false",
  }
}
```

# GASのトリガーを設定する
**sendZoomUrlToSlack関数**を定期実行するようにスケジュールを設定する。

# おわりに
はじめてGASを使ったが、めちゃめちゃ便利だと思った。
JWT Tokenについても学べたので楽しかった。
url scheme must be http or https for cors requestのエラー

# 作業環境
- AWS API Gateway
- AWS Lambda
- swagger(Open API)

# トラブルの内容
- swaggerで発生するエラーです。
- swaggerでhttpメソッド(get,putなど)の「execute」ボタンを押下したら、`url scheme must be http or https for cors request`というエラーが発生しました。

# 解決方法
- AWS API Gatewayで「CORSの有効化」をしていなかったことが原因でした。
  - リソースを選択した後、アクションのドロップダウンから「CORSの有効化」を選択することができます。
  - `CORSを有効化`した後は、`APIをデプロイ`するのも忘れないようにしましょう。

# 参考ページ
- [https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-cors-console.html](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-cors-console.html)
  - AWSの公式ページです。 
- [https://qiita.com/silverbox/items/43ecb047908a9580f7bd](https://qiita.com/silverbox/items/43ecb047908a9580f7bd) 

# 感想
- 自分の作業した流れは、以下の通りです。
  - Lambda単体で正しいレスポンスが返ってくることを確認する。
  - API Gatewayとlambdaを連携してAPI GatewayでテストしてLambdaが正しいレスポンスが返ってくることを確認する。
  - swaggerからAPI Gatewayを実行して正しいレスポンスが返ってくることを確認する。
- このような流れで作業を進めていって、表題のトラブルに遭遇しました。
- 「CORSとは何か」もっと勉強する必要があると感じました。
ConoHa VPS 公開鍵認証でSSH接続


#はじめに
ConoHa VPSへデプロイする際に公開鍵認証でのSSH接続手順を忘れがちなので備忘録として書きます。初学者やConoHa VPSを初めて利用する方々の役に立てればと思います。

#もくじ
- [環境](#環境)
- [SSH Keyを発行する](#SSH Keyを発行する)
- [サーバー追加時にSSH Keyを選択する](#サーバー追加時にSSH Keyを選択する)
- [ファイル配置とsshコマンド簡略化](#ファイル配置とsshコマンド簡略化)
  - pemファイルの移動とconfigファイルの作成
  - configファイルの記述 
- [ディレクトリとファイルの権限を設定する](#ディレクトリとファイルの権限を設定する)
- [SSH接続する](#SSH接続する)


##■環境
| 種別        | 名称 (バージョン)         |
|:-----------|:-----------------------|
| ローカル環境  | macOS 11.2.3          |
| サーバー環境 | ConoHa VPS CentOS 8.3  |

##■SSH Keyを発行する

ConoHa VPSの[ご利用ガイド](https://support.conoha.jp/v/vps_sshkey/)にあるとおり、SSH Keyを作成します。
SSH Keyを作成すると、秘密鍵（pemファイル）のダウンロード画面が表示されるのでダウンロードします。秘密鍵は認証時に必要となるファイルです。作成時の**一度しかダウンロードできない**ので大切に保管しましょう。もし、ダウンロードし忘れたり削除してしまった場合はSSH Keyを再作成して下さい。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1576152/87619edc-3344-4d7f-c694-433d8dc845bc.png" width="80%">
_画像は[ご利用ガイドページ](https://support.conoha.jp/v/vps_sshkey/)より拝借_

##■サーバー追加時にSSH Keyを選択する

サーバー追加画面最下部の「オプションを見る」をクリックすると、オプションがいくつか表示されます。SSH Key項目の「キーを選択」をクリックすると、「パブリックキーを選択」が表示されるので、先ほど作成したSSH Keyを選択する。（ここでSSH Keyを新規作成できるようだが試したことないので割愛）

>上記の手順で生成したSSH Keyを設定して追加したサーバーは自動的にパスワード認証が禁止となります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1576152/1084159a-e769-3131-33b8-bc5869839d58.png" width="80%">
_画像は[ご利用ガイドページ](https://support.conoha.jp/v/vps_sshkey/)より拝借_

##■ファイル配置とsshコマンド簡略化

###◇pemファイルの移動とconfigファイルの作成
SSH Key作成時にダウンロードしたpemファイルを.sshディレクトリ直下（~/.ssh/）に移動させます。ダウンロードしたpemファイルは数字の羅列だった気がするので、他のpemファイルと混同しないようにこのタイミングで名前を変更しておくといいです。（.sshディレクトリがない場合は作成してください。）

```
mkdir ~/.ssh
```

次にsshコマンドを簡略化するためにconfigファイルを.sshディレクトリ直下に作成します。
現時点で.sshディレクトリ内は下記のようになっていると思います。（既にssh接続を行ったことがある方は他のpemファイルやknown_hostsファイルがあるかもしれませんが問題ありません。）

```
.ssh
 ├── config　（新規作成）
 ├── hogehoge.pem　（移動させたpemファイル）
```

###◇configファイルの記述
configファイルにviコマンドなどで下記を記述します。

```~/.ssh/config
Host conoha_hoge（任意のエイリアス）
  HostName リモートのホスト名（契約したサーバーのIPアドレス）
  port 22
  User root
  IdentityFile ~/.ssh/hogehoge.pem
```

- Host：エイリアスはsshコマンドを実行する時に使用する名前です。名前は任意ですが、ここでは例として「conoha_hoge」として説明します。
- HostName：サーバーのIPアドレスはConoHaのサーバ情報から確認できます。
- port：セキュリティなどの理由からSSHのポートを変更する場合は編集してください。
- user：初期の接続と仮定してConoHaの登録済みユーザーである「root」を例として設定してます。
- IdentityFile：pemファイルのパス。

##■ディレクトリとファイルの権限を設定する
ここまできたらあともう一息です。「.sshディレクトリ」、「configファイル」、「pemファイル」の権限を設定します。
設定の詳細について調べたい方は[こちらの記事](https://qiita.com/shisama/items/5f4c4fa768642aad9e06)が分かりやすいと思います。

```
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
```

pemファイルの名前は各自異なると思うので変更してください。

```
chmod 400 ~/.ssh/hogehoge.pem
```

##■SSH接続する

下記コマンドでSSH接続してください。

```
ssh conoha_hoge
```

#おわりに

自分でVPSを動かしながら本記事を書きましたが、何か間違いや不具合などあればお手柔らかにご指摘いただければ幸いです。この後、セキュリティを高めるために「ルートユーザーでのSSH接続を無効化」などが必要な場合がありますが、本題の主旨とは異なる内容ですので他の方の記事を参照してください。




#参考文献
- [ConoHa VPS ご利用ガイド](https://support.conoha.jp/vps/guide/?btn_id=v-vps_ssh-sidebar_vps-guide)

#発展
ConoHaに限らず公開鍵認証でリモートにSSH接続する方法についての記事があったので、機会があればこちらの記事を参照する。

- [SSH公開鍵認証で接続するまで - Qiita](https://qiita.com/kazokmr/items/754169cfa996b24fcbf5)
- [Macで公開鍵と秘密鍵を生成する方法 - Qiita](https://qiita.com/wakahara3/items/52094d476774f3a2f619)
[React]defaultPropsは使わない！propsにデフォルト値を設定したいときはデフォルト引数を使おう

Reactで関数コンポーネントを作った時、propsにデフォルト値を設定したいことがあると思います。

例えば、下記Tableコンポーネントの場合、利用箇所が4つありますが③以外は全て'hoge'と指定しています。

```react
export default function Table({ hoge }: { hoge: string }) {
  return (
    <div>{hoge}</div>
  );
}

// 利用箇所①
<Table hoge='hoge' />

// 利用箇所②
<Table hoge='hoge' />

// 利用箇所③
<Table hoge='hogehoge' />

// 利用箇所④
<Table hoge='hoge' />
```

上記のように利用箇所ごとに指定しても良いのですが、よく指定される'hoge'をpropsのデフォルト値に設定したくなります。

そんなときに私はやり方がわからなかったのでGoogleで下記のように調べました。
下記は2021年8月に`react props デフォルト`で調べた結果です。

![スクリーンショット 2021-08-25 1.08.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83424/fd2042d7-d774-b110-b175-a10dcb8cc395.png)

上位7つを見てみました。
propsのデフォルト値について書いていないものも混じっていますが、デフォルト値について書かれている記事は全て`defaultProps`を使うように説明されていました。

実際に`defaultProps`を使って実装しても実現できるのですが、実は**ES6で追加されたデフォルト引数を使う方が良いとされています！！**

理由などは下記のStack Overflowを参照してください。

https://stackoverflow.com/questions/47774695/react-functional-component-default-props-vs-default-parameters

デフォルト引数を使うと最初の例は下記のように書けます。

```react
export default function Table({ hoge = 'hoge' }: { hoge?: string }) {
  return (
    <div>{hoge}</div>
  );
}

// 利用箇所①
<Table />

// 利用箇所②
<Table />

// 利用箇所③
<Table hoge='hogehoge' />

// 利用箇所④
<Table />
```

この記事の内容は知っている人からすると何を今更・・・って感じの内容だと思いますが、Google検索上位には今でも`defaultProps`の記事が溢れています。
知らない人がググったときに`defaultProps`にたどり着く確率を少しでも下げられたらいいなーと思い書いてみました。
Proxmox でVMの電源OFFができなくなった時の対応

#VMが固まってしまった:thinking:

```
can't lock file '/var/lock/qemu-server/lock-102.conf' - got timeout
```

のようなメッセージがでてGUIではなにもできなくなってしまった。
一時停止、停止、シャットダウンいろいろやってみる

結論から書くと

`lsof /var/lock/qemu-server/lock-102.conf `
でPIDをしらべて

`kill -9 pidの番号` 
でプロセスを落として

`qm stop 102`
で止める


なんで止まらないのかよくわからないが
OSインストール直後のエージェントが入ってない状態で止まりやすい。
CDを途中で抜くからかな:thinking:
TypeScriptでF5するときの不都合をとりあえず解決した話。

## 何が問題か？

単純な関数の実行結果の確認はVSCode上で確認したいが、ビルドするファイルのどれかにimport/exportの記述がある(つまりモジュールを使っている)場合、index.htmlのF12画面かVSCodeのコンソール画面でエラーが出てくる。
エラーのパターンは以下の通り。

- index.html側でexports is not definedエラーが出る(うまくビルドできてない)
- コンソール画面でTo load an ES module, set “type”: “module” in the package.json or use the .mjs extension……のエラーが出る

## 原因

index.htmlでエラーが出る原因はtsconfig.jsonのこの辺り。

```json

{
  "compilerOptions": {
    "target": "es2020", 
    "module": "es2015", 
    "esModuleInterop": true, 
  },

}


```

まず "target": "es5"とかだと古すぎるので怒られたりする場合がある。
が、もっと問題なのは"module"の部分。
ここが"module": "commonjs"とかだとindex.htmlでexports is not definedエラーがでる。
これはなんでかというとcommonjsがimport/exportに対応してない(commonjsだとexports.methodといったような感じで書く。モジュールだとexport{method})からなので、ts側でimport/exportの記述をし、"module": "commonjs"でビルドすると、"esModuleInterop": trueが作用して(commonjsとES6)でのミスマッチを解決するオプション)

```js

Object.defineProperty(exports, "__esModule", { value: true });


```

という一文が書き足されて解決されるはずなのだが、何故かこの一文を指してexports is not definedと出てきてしまう。
おそらく対処としては[このあたり](https://usefuledge.com/electron-typescript-export-is-not-defined.html)が適切なのかと思うのだけども、解決方法があんまりスマートではないので以下の通り対処した。

**追記

先程のリンク先のページから元のStackflowを辿ってみると、どうやらTypeScriptのバージョンアップに伴う仕様変更から起きているみたいで2.1.6だと発生しない。
けど、それは4年前の話で今は4.3.5とかなのにまだ解決していないとみると、module使うならもう"module": "commonjs"やめなさいよってことなのかもしれませんね。

## 対処

"module": "es2015"とmoduleのバージョンを上げてimport/exportに対応させる(targetが2020なら別にes2020でもいいと思う)。

私はとりあえず、

```json

{
  "compilerOptions": {
    "target": "es2020", 
    "module": "es2015", 
    "lib": [
      "es2020",
      "dom"
    ], 
    "esModuleInterop": true, 
  },

}


```

と、libプロパティも指定しておいた。
これでindex.html側は解決したが、今度はコンソール側で


```

To load an ES module, set “type”: “module” in the package.json or use the .mjs extension

```

と出るようになってしまう。
これはmoduleはそもそもPackage.jsonありきなんだからそれ用意するか.mjsの拡張子つけなさいよってことなのでそうすればいい。
なのでpackage.jsonを作って

```json

{
  "name": "typescript-tutorial",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "tsc",
    "build:watch": "tsc --watch"
  },
}


```

こうしておく。
すると、コンソール側でも問題なくF5でconsole.logの実行結果等を確認できるようになった。

## 最後に

これがベストプラクティスかと言われると素人の生兵法だと思いますが、私は単純な関数はF5でDOM要素が必要ならブラウザで確認したいので上記のような解決方法を取りました。
tsconfig.json含むVScodeでのTypeScipt開発環境及びデバック環境のベストプラクティスご存じの方いたらぜひご享受ください。
Powershellでフォルダアクセス権を手軽に確認する

**注意　本稿はフォルダアクセス権についての記事になります。共有フォルダアクセス権には一切触れません。**

Powershellで対象フォルダ/ファイルのアクセス権を確認しようと思ったら、以下のようなコマンドを実行することになると思います。

```powershell
PS E:\> Get-Acl E:\test
```
ほいで出力結果が以下のとおりですかね。

```
    ディレクトリ: E:\


Path   Owner           Access
----   -----           ------
test domain\maganemi   domain/Domain Admin Allow  FullControl.......
```

おわかりいただけただろうか。
特殊な環境でもなければ、通常はビルトインアカウント(AdministratorやSYSTEMなど)が予め4個程度すでに付与されています。
ところが、実行結果からは一行しか見えていません。
要は改行された先(2つ目の権限以降)の情報がみえていない状態となります。

なので、以下コマンドを実行することでこの問題を解決します。

```powershell
(get-acl test).Access
```
上記のように、表示したい項目のみを表示するようコマンドをカッコで囲ってプロパティを指定します。

```
FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : BUILTIN\Administrators
IsInherited       : True
InheritanceFlags  : None
PropagationFlags  : None

FileSystemRights  : 268435456
AccessControlType : Allow
IdentityReference : BUILTIN\Administrators
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : InheritOnly

FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : NT AUTHORITY\SYSTEM
IsInherited       : True
InheritanceFlags  : None
PropagationFlags  : None

FileSystemRights  : 268435456
AccessControlType : Allow
IdentityReference : NT AUTHORITY\SYSTEM
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : InheritOnly

FileSystemRights  : Modify, Synchronize
AccessControlType : Allow
IdentityReference : NT AUTHORITY\Authenticated Users
IsInherited       : True
InheritanceFlags  : None
PropagationFlags  : None
```

あー長い。こうすると権限一覧だけでなく、その他のややこしいプロパティまで全部でてきてしまうんよね。そういうんじゃないんだよ。
もっと絞ります。必要なのは「IdentityReference」だけやからね。

```powershell
PS E:\> (Get-Acl E:\test).Access | select IdentityReference
```
ほいで結果がこのような感じですな。

```
IdentityReference
-----------------
BUILTIN\Administrators
NT AUTHORITY\SYSTEM
NT AUTHORITY\Authenticated Users
BUILTIN\Users
```
そうよぉ。これよこれ。

コマンドも難しくなく、結果もわかりやすいので非常に使い勝ってよく重宝します。
大量フォルダのアクセス権抽出時にこそ真価を発揮しますな。

```powershell
foreach ( $FolderList in Get-ChildItem -Path C:\ -Recurse) {(Get-ACL $FolderList).Access | select IdentityReference | -join ($FolderList,",",$_.IdentityReference)}
```

まぁ利用する機会があるかどうかはわからないけど。私はありました。

以上です。サヨナラ
ロジカルシンキング（論理的思考力）を伸ばす方法

#論理的思考能力とは？
ロジカルとは、「論理的な」「筋の通った」という意味です。
論理的思考とは、物事を体系的に整理し、矛盾や飛躍のない筋道を立てる思考法です。
とくに問題の解決策を考える場面で力を発揮します。

#言葉を具体的にする

日々の何気ない会話の中の「抽象的な言葉」を「具体的な言葉」に変えることが、論理的思考のトレーニングになります。
例えば、 普段こういった言葉を使ってしまう人は気を付けてみましょう。

・「やるべきことに注力して、目標達成に向けて頑張ります」 →具体的に何をやるのか明確にする。
・「早めに提出します」 →具体的な期日を伝える。

特に、後者の「早め」の感覚は人によって異なります。
抽象度が高い言葉は、自分の伝えたいことが相手に正しく伝わっていないことがあります。
全ての人が同じイメージができるように伝えるためには、より具体的に言葉を定義する必要があります。
【初心者向け】影を薄くする方法

Unity を操作しているときに、影が濃いなと思うことありませんか？
これは簡単に薄くすることができます。

# 要約？
Direction Light の Shadow Type/Real Shadows/Stregnth を操作するだけ。
![adjusting_shadow.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/6e721d1e-3813-89de-a97e-be43763ec8de.gif)
Laravel attribute original の違い

#dd()するとよく出てくるこの二つの違いについて調べてみました。

![スクリーンショット 2021-08-25 0.55.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670485/0333391c-6e38-879b-4092-0303bbfe8a4a.png)

#それぞれの違い

##original

originalは名前の通りオリジナルのデータになります。
コレクション型でデータを引っ張ってきてdd()するとoriginalにデータが入ります。

```php:MainController.php
$boxes = Box::orderBy('created_at', 'asc')->get();
dd($boxes);
```


##attribute

こちらは加工したデータが入ります。
下記のようにmap()関数でdistanceというカラムを増やしてあげると

参考
Laravelのモデルの結果セットに「任意のカラム」を追加する
https://pgmemo.tokyo/data/archives/1384.html

```php:MainController.php
  $boxes->map(function($item,$key) use ($my_lat,$my_long){

    $item['distance'] .= $item->get_distance($my_lat,$my_long);
    return $item;
   });
   dd($boxes);
```
![スクリーンショット 2021-08-25 1.06.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670485/b4c04be1-fe24-65f3-1645-f76dd0deeaeb.png)

attributeの項目が増えます。

#感想
意味がわかると面白い
Linux Ubuntu20.04にMATLABをインストールして起動してみた

# はじめに
自分のノートPCでは限界が来て, 今回研究室のlinux環境にMatlabやらUnity, UEやらをインストールすることになった.
Matlabをlinuxにインストールして起動するまでの過程をまとめてみた.
(**注意**: これは研究室の作業環境にインストールした物である. そのため各ユーザ毎にインストールを想定して作業したログである.)

```:環境とMatlabのverについて
Ubuntu ver  : 20.04
MATLAB ver  : R2021a
```
# インストール作業
## MathWorksのアカウント作成
これをしないと始まらない.
大学が提携していたため, その手順に従って作成した.
このアカウントのライセンスを用いて後のインストール作業を行う.
割愛~

## zipファイルからMatlabをインストールする
大学のLinuxにvnc接続して作業を行なった.
MathWorksの公式ページに飛んで, 登録した学生アドレスを用いてログインする.

インストールしたいリリースとlinuxを選択.

~/Downloadsにzipファイルをダウンロード.(R2021aを選択した)
![20210824matlab_release.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255841/1ced8d85-8c77-719f-7b6c-58dc2636dcd3.png)


```
$ cd ~/Downloads
$ mkdir matlabR2021a_unzipdir
$ mv ~/Downloads/matlab_R2021a_glnxa64.zip ~/Downloads/matlabR2021a_unzipdir
```
(この作業は個人的にDownloads内にファイルがばら撒かれたくないため行なった, 気にならなければ行わなくても大丈夫)

```
$ cd ~/matlabR2021a_unzipdir
$ unzip matlab_R2021a_glnxa64.zip
```

zipを作成したディレクトリ内で解凍する.

```
$ mkdir /xxx/xxxx/xxxx/MatlabR2021a
```

matlabをインストールしたい場所にフォルダを作成しておく.

```
$ ./install
```
実行すると, installerが起動する.
![20210824matlabInstaller.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255841/c1f12950-3156-0f37-04e5-5b8a9f8491cb.png)

https://jp.mathworks.com/help/install/ug/install-products-with-internet-connection.html

公式ページの手順に従い,

* 学生アカウントへのログイン
* 学生アカウントのライセンスを選択
* Select destination folderは作成した/xxx/xxxx/xxxx/MatlabR2021aを選択
* インストールしたい製品を選択
* Select optionsでは"Create symbolic links to MATLAB scripts in: "は選択せずに進む
* 最終確認を行いインストールを開始する.

製品と環境によっては少々~かなり時間がかかると思われる.

# MATLABの起動
https://jp.mathworks.com/help/matlab/matlab_env/start-matlab-on-linux-platforms.html

公式ページを参考に.

```
$ cd /xxx/xxxx/xxxx/MatlabR2021a/bin/
$ ./matlab
```

でMatlabが起動される.

しかし初回時は起動できず,以下が出力された.

```
$ ./matlab
MATLAB is selecting SOFTWARE OPENGL rendering.
Cannot locate or initialize class com/mathworks/jmi/OpaqueJavaInterface.
java.lang.NoClassDefFoundError: com/mathworks/jmi/OpaqueJavaInterface
Caused by: java.lang.ClassNotFoundException: com.mathworks.jmi.OpaqueJavaInterface
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
```

調査すると, いくつかパッケージをインストールする必要がある様だった.

オプション -glnx86

を付与してもう一度起動してみると起動できた.

```
$ ./matlab -glnx86
```

後日, オプションなしで起動してみたところ, 一応起動は確認できた.
(パッケージはインストールしてない...)

```
$ ./matlab
MATLAB is selecting SOFTWARE OPENGL rendering.
Gtk-Message: xx:xx:xx.xxx: Failed to load module "appmenu-gtk-module"
```

# 補足
動作確認はまだしていないため, 色々問題が起こる可能性もあるが, ひとまずインストールから起動まで確認できた.
後に問題が発生した場合はそちらもまとめたいと思う.

# 参考文献
1. [インターネット接続を使用した製品のインストール](https://jp.mathworks.com/help/install/ug/install-products-with-internet-connection.html)
2. [Linux プラットフォームでの MATLAB の起動](https://jp.mathworks.com/help/matlab/matlab_env/start-matlab-on-linux-platforms.html)
3. [64bit版 Ubuntu で32bit版(学生版) MATLAB を動かす方法 ](https://ill-identified.hatenablog.com/entry/2014/01/12/210409)
【Powershell】ActiveDirectoryの全セキュリティグループとその所属ユーザ一覧作成方法

Active Directory に登録されているグループをすべて抽出し、そこからユーザ一覧をしようと思ったら以下のコマンドになると思います。

```powershell
Get-ADGroup -Filter * | Get-ADGroupMember
```

これならたしかにすべてのグループに所属するユーザが抽出できますね。
ただこれには一つ問題があります。

上記コマンドで出力される結果は単なるユーザ情報でしかなく、**どのグループからパイプ処理で渡され出力されたユーザか**なんて情報は持ってません。
こういったコマンドを打つ場合っていうのは大抵棚卸しが目的なので、それを要求している場合がほとんどです。

以下、それを実現するためのコマンドです。

```powershell
foreach ($GroupList in Get-ADGroup -Filter *) {Get-ADGroupMember $GroupList | -join ($GroupList.Name,",",$_.Name,",",$_.SamAccountName)}
```
このコマンドであれば**このユーザはこのグループに所属しているんだな**というのが一目瞭然です。
また、上記コマンドでは各項目間の区別を容易にするため、カンマで区別するいわゆる**カンマセパレート**をしています。
例えば、グループ名などにカンマを使っちゃってるクソめんどくせぇ運用している場合は**チルダ**とか比較的利用頻度の低い文字列をセパレートに利用すると区別しやすいですね。

Powershellでは、データのファイル出力にexport-csv以外を使った場合、項目間の区別にスペースを使うことがあり、しかも見栄えをよくするためにスペースの数がランダムだったりして集計殺しだったります。
今回のようなことが目的の場合はexport-csvでの出力も叶わないのでなおさらですね。

```
？「あれ？出力結果は？例とかでもいいから見せてよ」

はぁ？会社の環境でやれ！情報を抽出するだけのコマンドなんだから読み取り権限のみのアカウントでやりゃいいだろ！
ただ膨大なユーザ数が抽出されるから、負荷にはきをつけてな。
```

以上です、よろしく。
OctaveをMacにインストールしようとしてつまづいたのでメモ

##最初に結論

- Octave-app.orgからダウンロードしてもbrew installしてもOSアプデしてもGUIが起動できなかった
- User/ユーザー名/.configにoctaveフォルダを新規作成してあげたら起動できた


##何でつまづいたのか
今までCourseraのMachine Learningの授業をWindows10/OctaveGUIで受講していたのだが、事情により途中からMacに切り替えることになった。
そこで、Octaveの最新バージョン（安定版）である6.2.0のdmgファイルをダウンロードして起動しようとしたのだが、control+右クリックで開くをクリックしても、アイコンをダブルクリックしても起動しなかった。
正確に言うと、初回起動時のウィザードは開くことができるのだが「次へ」ボタンをクリックして起動に進もうとしても直後にOctaveGUIが落ちてしまう状態だった。この時点でターミナルからは起動ができて演算も問題なしという状況である。

6.3.0(ベータ)やかなり古い4.xあたりを試すも起動できず。
Homebrewを使ったインスールも試してみたところ、以下のエラーが出た

```bash
Warning: You are using macOS 10.12.
We (and Apple) do not provide support for this old version.
You will encounter build failures with some formulae.
Please create pull requests instead of asking for help on Homebrew\'s GitHub,
Twitter or any other official channels. You are responsible for resolving
any issues you experience while you are running this
old version.
qt@5: A full installation of Xcode.app is required to compile
this software. Installing just the Command Line Tools is not sufficient.
Xcode can be installed from the App Store.
Error: An unsatisfied requirement failed this build.
```
##
 
Xcode.Appが必要らしい。
早速Appstoreで入手しようとするも、OSのバージョンが古いため最新バージョンはインストールできない。[ここ](https://developer.apple.com/download/all/)から旧バージョンを入手

##
```bash
>Error: Failed to download resource \"flac\"
Download failed: Homebrew-installed \`curl\` is not installed for: https://downloads.xiph.org/releases/flac/flac-1.3.3.tar.xz
(base) xxxx:~ xxxx$ brew install octave
Warning: You are using macOS 10.12.
We (and Apple) do not provide support for this old version.
You will encounter build failures with some formulae.
Please create pull requests instead of asking for help on Homebrew\'s GitHub,
Twitter or any other official channels. You are responsible for resolving
any issues you experience while you are running this
old version.
```

##

curlをインストールせよとの警告に従い、brew install curlコマンドを実行
これがバカ重い、かなり時間かかるので放置

## OSをアップデートしてみる
ずいぶん古いバージョンのmacOSを使用していたので、今更だが最新のBig Sur11.5.2にアプデしてみた。
その上で上記手順を繰り返すも進展なし。

## .configフォルダ内にoctaveフォルダを作成したら起動できた
初回起動時のメッセージで.config内にこんなファイル作るで〜と言っているのだが、実際に当該ディレクトリを見に行ってみると.config内は空っぽであった。もしや、と思いここに手動で新規フォルダを作成し名前をoctaveとして保存。
アプリケーションを開き、octave(GUI)のアイコンをcontrol+右クリックで開く、初回メッセージを「次へ」連打で飛ばすと無事GUIを起動できた

##反省
OSのアプデを最初に検討していれば、インストーラをダウンロードした時点でインストールに成功したかもしれない・・・
初回起動時にconfigフォルダ内に設定ファイルが自動的に作られなかったのも、結局原因は特定できなかった。
homebrewやbashについて勉強になったのでヨシ、ということにしておきたい。
マルチプラットフォーム Docker ビルドを kaniko で行う

# これは何?

[kaniko](https://github.com/GoogleContainerTools/kaniko) を使って, [docker buildx](https://matsuand.github.io/docs.docker.jp.onthefly/buildx/working-with-buildx/) みたいなことをする話です.

# 結論

docker run の引数に `--platform` つけ, それに対応する kaniko の image をしていす
ただし,  linux/amd64, linux/arm64, linux/ppc64le の3種類のみ対応しています.

# 想定読者

- docker in docker をやりたくない人

# 想定していない読者

- Kubernetes 使う人

# 詳細

kaniko は [customPlatform](https://github.com/GoogleContainerTools/kaniko#--customPlatform) の説明にあるように, 異なるアーキテクチャに向けた docker image のビルドはできません.
ですが, kaniko 自身は [v.1.5.0](https://github.com/GoogleContainerTools/kaniko/releases/tag/v1.5.0) から multi-platform image となり, 3種類のプラットフォームで動作することができます.

ということで, 作成する docker image のターゲットプラットフォームで, kaniko を動かせば OK ということです.

`linux/arm64` の docker image を作成するなら, 次のように platform 指定します.

```bash
docker run --platform linux/arm64 -v "$context":/workspace \
  gcr.io/kaniko-project/executor:latest@sha256:1eaf7551bcc48b9a31deac4781433fabcd8ca633c4c0a3c61a281d4ec1fffa41 \
  --dockerfile "${dockerfile}" --destination "${destination}" --context dir:///workspace/
```
【React】React ことはじめ (ただの学習ログ)

## きっかけ
- 過去にAngular, Vue.jsを使用した開発は行ったことはあるが、Reactはなかったため。

##学習の進め方
- ちょうど[基礎から学ぶ React/React Hooks](https://www.amazon.co.jp/基礎から学ぶ-React-Hooks-asakohattori/dp/486354359X)の発売日だったため、準拠しながら進めていきたい。
- 記事の記載に間違いがある場合、マサカリをお願いします…

## 学習内容
### Reactとは?
- UIを構築するためのJavascriptライブラリ
    - Vue.js,Angularはフレームワーク(いづれも公式サイトにフレームワークの記載あり)
- Reactの特徴
    - コンポーネント指向
        - ソフトウェア開発をコンポーネントに分けて進める考え方。コンポーネント=画面構成要素(ボタン、入力フォーム...etc) 
        - Vue.js, Angularでもコンポーネント指向を採用
    - 仮想DOMによる高速レンダリング
        - 変更前後の仮想DOMを比較し、変更差分のみリアルDOMに反映することでページ表示の高速化を実現
        - こちらもVue.js, Angularでも採用されている


### Reactの使い方
- CDNを利用し、HTMLファイルでReactを使用
    - Webサイトが重くなるため、デモなどで使用し、本番環境には適さない
- CodeSandboxなどのオンラインエディタでReactを使用
- ローカルでNode.jsなどをインストールし環境構築後、Reactを使用(Create-React-Appなど)

### 補助ツール
ReactではWebpackでファイルをまとめる過程でBabelにて過去バージョンのJavaScriptに変換される

- Babel
    - JavaScriptを他の構文のJavaScriptに変換するトランスパイラ
    - 基本的にJSXなどの新しい構文を過去のバージョンに変換する
- Webpack
    - 複数のファイルを纏めるモジュールバンドラ
    - パフォーマンス向上に寄与

### React Hooksとは
- もともと関数コンポーネントではStateなどのReactの機能を使用できなかったが各種フック関数で使用できるようになった
- フックはReactの機能に接続するための関数コンポーネントで使用できる関数

### 各種フック
- useState
    - 状態を管理するフック
    - const [状態変数, 状態を変更するための関数] = useState(状態の初期値)
- useEffect
    - 渡された関数の実行タイミングをコンポーネントのマウント後、アンマウント後、または更新後まで遅らせる(制御できる)フック
    - useEffect(関数名, [依存する変数の配列])
    - 配列が空配列だと初回レンダリングのみ実行
    - 変数の配列があるとその変数に変化があると実行
- useContext
    - ツリー内のいずれの階層からContextに格納されているデータにアクセスできる
    - contextオブジェクト、Providerコンポーネント、Comsumerコンポーネントが必要
- useCallback, useMemo
    - メモ化: 初回のみ実行、記録 ⇒同じ値の2回目は保持された計算結果を使用
    - パフォーマンス向上に寄与
    - useCallbackは関数自体のメモ化 ⇔ useMemoは実行結果をメモ化、保持