OmniAICreator/Qiita-1.07M huggingface dataset:
IntelliJでSpringBootのWebアプリケーション開発

# 環境

|項目|値|
|---|---|
| 開発環境 | IntelliJ IDEA 2022.1.4 (Ultimate Edition) |
| SpringBoot | 2.7.2 |
| Java | 11 |

# プロジェクトの作成

IntellJの新規プロジェクト作成でSpring Initializrを選択して以下のように入力。

![スクリーンショット 2022-08-06 13.02.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/4cee236f-8040-ed70-2199-d88de34bef70.png)


シンプルに**Spring Web**と**Thymeleaf**だけを選択します。

![スクリーンショット 2022-08-06 13.03.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/860d7bc2-4ebe-78ba-9ee2-cc6299c56503.png)

作成をクリックするとプロジェクトが作成されます。

![スクリーンショット 2022-08-06 13.07.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/ec0e492b-c58a-a072-4e4e-fb308d8159fa.png)


# 実行

実行をクリックするともう起動できる状態になっている！

![スクリーンショット 2022-08-06 13.07.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/d130c597-73da-ded0-904b-f4197faa59b3.png)


![スクリーンショット 2022-08-06 13.08.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/64e10b12-f620-e74a-aecc-afc8a16c5608.png)

以下にアクセスしてみると。

[http://localhost:8080](http://localhost:8080)

もしろんページの実装がないのでエラーになりますが・・・

![スクリーンショット 2022-08-06 13.09.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/f738a57c-c61b-45af-3788-e300ea21fb41.png)

# トップページを作成

## コントローラを作成

controllerというパッケージを作成する。
名前はappとかでも良いです。

![スクリーンショット 2022-08-06 13.14.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/d23a3840-6b79-cf8e-68ab-d170f94f18fe.png)

![スクリーンショット 2022-08-06 13.15.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/0803972a-f5f0-06d2-c1fc-fa31e821fa80.png)

controllerの下にIndexController.javaファイルを作成します。

![スクリーンショット 2022-08-06 13.15.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/265ff54d-4b8e-d367-b030-f0ed217c2d16.png)

![スクリーンショット 2022-08-06 13.15.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/81158801-29a2-f330-a854-34ffa754cb1d.png)

内容な以下のように書き換えます。

```java:IndexController.java
package com.ykdevs.springsample.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class IndexController {

    @GetMapping("/")
    public String index() {
        return "index";
    }
}
```


## テンプレートを作成

main/java/resources/templates以下にindex.htmlを作成します。

![スクリーンショット 2022-08-06 13.20.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/a4248786-34ea-47f9-3151-efcbd3a3e55c.png)

![スクリーンショット 2022-08-06 13.22.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/2a965929-afea-5f15-fd11-0ba7f19f7f0d.png)

内容は以下のようにします。

```html:index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test Page</title>
</head>
<body>
Hello World!!
</body>
</html>
```

## 実行する

![スクリーンショット 2022-08-06 13.24.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/7b9db84b-31bf-5b1e-1648-905c207489ce.png)

こんどはちゃんと表示されます。

![スクリーンショット 2022-08-06 13.24.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81113/bf2535f4-a443-def6-ab1d-208da9f526c4.png)
はじめてのGo

# まずはGoのInstallから
<!-- 発端や概要を記載 -->
とりあえずGinというフレームワークでREST APIを作る想定で学習してみよう。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [GoのInstall](#Chapter1)
1. [GinのInstall](#Chapter2)
1. [コードを書く](#Chapter3)
1. [APIを実行してみよう](#Chapter4)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# GoのInstall
MacならbrewでInstall可能
```
taka$ brew install go
```

ちゃんとInstall出来たか確認しよう
```
taka$ go version
go version go1.18.5 darwin/amd64
```

パスの設定がうまくいっているか確認しよう
```
taka$ go env GOROOT
/usr/local/Cellar/go/1.18.5/libexec

taka$ go env GOPATH
/Users/taka/go
```


<a id="#Chapter2"></a>
# GinのInstall
GOPATHに合わせてディレクトリを作成する
```
taka$ mkdir go
taka$ cd go
taka$ mkdir test-gin
taka$ cd test-gin/
taka$ go mod init test-gin
taka$ go get -u github.com/gin-gonic/gin
```


<a id="#Chapter3"></a>
# コードを書く

エンドポイントの設定とレスポンスを返す関数を作成してみよう
https://github.com/oretanegi/test-gin/blob/master/main.go
(サンプルは公開していますので、こちらでもどうぞ

```go
package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

func home(c *gin.Context) {
	// :nameから値を取り出す
	name := c.Params.ByName("name")
	c.JSON(200, gin.H{
		"message": fmt.Sprintf("hello %s", name),
	})
}

func instruments(c *gin.Context) {
	var instruments [3]string
	instruments[0] = "piano"
	instruments[1] = "guitar"
	instruments[2] = "bass"

	c.JSON(200, gin.H{
		"message": instruments,
	})
}

func games(c *gin.Context) {
	var games [2]string
	games[0] = "BanG Dream!"
	games[1] = "ragnarokorigin"

	c.JSON(200, gin.H{
		"message": games,
	})
}

func main() {
	router := gin.Default()

	router.GET("/:name", home)
	router.GET("/instruments", instruments)
	router.GET("/games", games)

	router.Run(":5000")
}
```

<a id="#Chapter4"></a>
# APIを実行してみよう

サーバを起動？
```
taka$ go run main.go
```

curlでアクセスしてみよう
```
taka$ curl -X GET localhost:5000/instruments
{"message":["piano","guitar","bass"]}
```

TypeScriptを覚えるよりは楽かも知れない。。。
(一応、C言語経験者ですし
Laravel スマホ 確認 Windows

# 環境
Windows 11 Home

# 手順
### 1. 自分のPCのIPアドレスを確認
- **「 Windows（ロゴ）キー ＋ I（アイ）」** のショートカットで設定を開く。
- **「ネットワークとインターネット」** 一覧を開く。
- **「Wi-Fi」** 一覧を開く。
- **「プロパティ」** 一覧を開く。
- **「IPv4 アドレス」** が自分のPCのIPアドレスとなるため、確認する。

### 2. ネットワークプロファイルをプライベートに変更
- **「 Windows（ロゴ）キー ＋ I（アイ）」** のショートカットで設定を開く。
- **「ネットワークとインターネット」** 一覧を開く。
- **「Wi-Fi」** 一覧を開く。
- **「プロパティ」** 一覧を開く。
- **「ネットワークプロファイルの種類」** を **「プライベート」** に変更する。

### 3. artisanコマンドで簡易サーバーを立ち上げる
```
php artisan serve --host IPアドレス
```

# 結果
スマートフォンで **``http://IPアドレス:8000``** にアクセスすればローカルの環境でLaravelで開発しているものが確認できるかと思います。

# 参考記事
- [Laravelのartisanでサーバを立ち上げた時にプライベートIPでアクセスできない問題と、その対処法](https://imamotty.hatenablog.jp/entry/2015/03/01/145221)
- [ローカル環境の開発内容を実物のスマホで確認する方法](https://bellbellbell.info/2020/08/check-local-env-from-smartphone/)
【超初心者向け】画面遷移について

# 最初に
この記事はswiftを勉強し始めた超初心者による超初心者のためのものになっているので、細かいミスなどが散見されるかもしれませんがご了承ください。

# 画面遷移の方法
#### ①segueとボタンのみで遷移する
![スクリーンショット 2022-08-02 午後8.35.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2763612/7265b7c0-ef99-e1c4-fd77-a5c4aa9afce7.png)
多分一番最初に学ぶやり方です。`storyboard` 上に `button` を置き、そこから別の `viewController` につなげます。その時、遷移の種類が求められるので、行いたい遷移に従って設定しましょう。これで、その `button` を押すと画面遷移がすることができるようになります。


#### ②segueとコードを利用した画面遷移
![スクリーンショット 2022-08-02 午後10.47.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2763612/c28f84df-79df-922c-18dc-1e1ad8771b0a.png)
```swift:ViewController.swift
class ViewController: UIViewController{

   override func viewDidLoad() {
      super.viewDidLoad()
   }

   @IBAction func next(_ sender: UIButton){
      self.performSegue(withIdentifier: "toNext", sender: nil)
   }
}
```
`segue` の `identifier` を設定し、それに応じて画面遷移をする方法です。

#### ③コードのみを利用した画面遷移
```swift: ViewController.swift
class ViewController: UIViewContorller{

   override func viewDidLoad() {
      super.viewDidLoad()
   }

   @IBAction func next(_ sender: UIButton){
      //遷移先のViewControllerが存在するstoryboardを宣言する。（この場合はこのViewControllerと同じところに存在するため"self"）
      let storyboard: UIStoryboard = self.storyboard!
      //遷移先のViewControllerを宣言する
      let nextViewController = storyboard.instantiateViewController(withIdentifier: "Next")
      //フルスクリーンで表示させる
      nextViewController?.modalPresentationStyle = .fullScreen
      //遷移の種類をcoverVerticalにする
      nextViewControlle?.modalTransitionStyle = .coverVertical
      //宣言したViewControllerを出現させる
      self.present(nextViewController, animated: true, completion: nil)
   }
}
```
`storyboard` 上で `segue` を設定せずに、コードのみで画面遷移を行う方法です。この場合、`segue` に` identifier` をつけたのと同様、遷移先の`ViewController`に`identifier`をつける必要があります。ちなみに、遷移の種類についてはアニメーション付きで分かりやすい記事が他にあるのでそちらを見てください。


#### ④NavigationControllerを使用した画面遷移
![スクリーンショット 2022-08-03 午前0.20.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2763612/c49dc322-a28c-8b2e-00c6-671e2bac74c9.png)
`NavigationController`を使用している場合、遷移の種類を`"show"(push遷移)`にすると、遷移の方向が横になり、自動的に戻るボタンも追加されます。

## 画面遷移の戻り方
#### ①segueを使用している場合(NavigationController無し)
```swift: NextViewController.swift
class NextViewController: UIViewController{

   override func viewDidLoad() {
      super.viewDidLoad()
   }

   @IBAction func back(_ sender: UIButton){
      self.dismiss(animated: true, completion: nil)
   }
}
```
#### ②NavigationControllerを使用している場合
`NavigationController`を使用している場合は、上述のように自動的に戻るボタンが設定されているので新たに`button`等を設定する必要はありませんが、コードを使用して戻る場合は下記のようになります。
```swift:NextViewContrller.swift
class NextViewController: UIViewController{

   override func viewDidLoad() {
      super.viewDidLoad()
   }

   @IBAction func back(_ sender: UIButton){
      self.navigationController?.popViewController(animated: ture)
   }
}
```


### 最後に
いろいろ細かいミスがあると思いますので、何かありましたらご指摘お願いします。
初めまして！yukkrisoft　laboratoryです！

こんにちは。こんばんは。

yukkrisoft laboratory（ゆっくりソフト研究所）です。

このnoteでは、vtuberになりたい人向けの動画や、動画編集方法など、

いろいろなことを、解説、紹介していきます。これからよろしくお願いします。

自己紹介サンプル動画↓↓↓↓↓
https://vimeo.com/736804580
【超初心者向け】UIButtonについて

# 最初に
この記事はswiftを勉強し始めた超初心者による超初心者のためのものになっているので、細かいミスなどが散見されるかもしれませんがご了承ください。

# buttonとactionの結びつけ
`button`と何らかの`Action`を結びつける方法は二つあります。（多分）

##### １．@IBActionを使用する方法
```swift
@IBAction func print(){
   print("ボタンが押されました")
}
```
`@IBAction`で宣言した関数は`storyboard`上で`button`と関連付けができるので、それを行って`action`を使用する方法です。`button`をどんな感じで押したときに`action`がされるのかっていうのは`storyboard`上で関連付けを行うときに決定します（`touchUpInside`とか）。

##### ２．@objcを使用する方法

```swift
@IBOutlet var button: UIButton!

override func viewDidLoad() {
   super.viewDidLoad()

   button.addTarget(target: self, action: #selector(print(_:)), for: UIControl.Event.touchUpInside)
}

@objc func print(_ sender: Any){
   print("ボタンが押されました")
}
```
`@objc func` で宣言した関数を `addTarget` で `button` にコード上で結びつける方法です。この場合、`button` と `action` の関連付けはコード上で行っているので、必要になる関連付けはUIパーツの `button` の関連付けです。
`addTarget` の中身については、`target` は基本的に `self`、`action` の中に `#selector(関数名(sender))` っていう形でそのボタンが押されたときの `action` となる関数を記述し、`for` にはどんなタッチイベントのときに起動するのかということを設定します。細かい話は別の記事を見てください。
ちなみに、このやり方は`GestureRecognizer` などを使用するときにも使えます。

###### senderについて
```swift
@IBAction func print(_ sender: Any){
}

@IBAction func print(_sender: UIButton){
}

@IBAction  func print(){
}

```
基本的には上のどれでもいけます。ただ `@objc` と `addTarget` を使用する場合は `sender` を未設定でいくとダメみたいです。

# buttonのカスタマイズ

```swift
@IBOutlet var button: UIButton!

override func viewDidLoad() {
   super.viewDidLoad()

   //ボタンの背景色を変える
   button.backgroundColor = .red

   //ボタンの文字を設定する
   button.setTitle("タイトル", for: .normal)

   //ボタンのフォント、文字サイズを設定する
   button.titleLabel?.font = UIFont(name: "フォントの名前", size: 20)

   //ボタンの文字色を変える
   button.tintColor = .blue

   //ボタンに画像を設定する
   button.setImage(UIImage(named: "画像の名前"), for: .normal)

   //ボタンに枠線をつける（枠線の太さを変える）
   button.layer.borderWidth = 3.0

   //ボタンの枠線の色を変える
   button.layer.borderColor = UIColor.black.cgColor

   //ボタンの枠線の丸みを変える
   button.layer.cornerRadius = 5.0

   //ボタンに影の明瞭さを変える
   button.layer.shadowOpacity = 0.7

   //ボタンの影の丸みを変える
   button.layer.shadowRadius = 3

   //ボタンの影の色を変える
   button.layer.shadowColor = UIColor.black.cgColor

   //ボタンと影の離れ具合を設定する
   button.layer.shadowOffset = CGSize(width: 5, height: 5)   
}
```


## 最後に
いろいろとミスってるところとかあると思うので、ご指摘お願いします。
MENTA でメンター業に挑戦してみたが、なかなか厳しい。

# 単価が安い

月3000円プランとか平気でやっている人がいる。値段で勝てる気がしない。

# メンティにお金がない

メンティは企業ではなく個人なので、そもそもの予算が少ない。

# プラン作成するだけでは誰もメンターを申し込まない

プロフィールやプラン、スキル登録などをこなしても勝手に契約が舞い込んできたりはしない。

少なくとも僕の場合はそうだった。

# メンターとメンティの行き違い

責任を明確にしておかないと、コストが膨れ上がる場合がある。

2500円の単発案件で70往復ほどのメッセージをしたにも関わらず、結局は抱えきれずに返金させてもらった案件もあった。

# 下積みをしても効果なし？

メンティ発信の「相談」に応募してメンティスコアを上げてみたが、特に今のところ自然な契約が舞い込んできたりはしていない。

# メンティによる「相談」では案件成立までが一苦労

まず良さげな相談を探してメッセージを送っても、返信がない場合も多い。

やっと契約が決まって単発の案件に応じ、メッセージでやり取りしたりオンライン通話をしてようやく報酬が発生し、しかもシステム利用料で20%ほどは差し引かれる。

なかなかに厳しい。

ちなみにMENTAの「メンターを募集」コーナーは、メンターを募集というよりほぼ、小さなタスク代行募集みたいになっている。

<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Windows PowerShell 5.1 から PowerShell 7 への移行

# Windows PowerShell 5.1 から PowerShell 7 への移行


## 1,Winget を使用して PowerShell をインストールする

https://docs.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.2#winget


## 2,Microsoft Store からインストールする

https://docs.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.2#msstore
続・自分のブログに海外からなんだかご機嫌なコメントが届いた件

# はじめに
https://qiita.com/watyanabe164/items/5da95fafa7341cfc4bff

でも怪しいコメントが届いたってネタを投稿したけど
今度も怪しいコメントが届いたので記録のために残す

# 同時多発テロ的なコメント
ありがたいことに７件ものコメントがきた。IPもバラバラなのでひょっとしたらそれぞれ別の人かもしれないのだけれども
気になるのは、
* コメントが全部一緒
* 投稿日がほぼ同時
* 投稿ページをクローリングしたかのように一つずつ読んで重複しているページがない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/fe2314dd-1780-4c27-44fe-a54a21ff0a1e.png)

ぬぬぬ…！怪しい。。。

# ここから得られる学び
仮に同じ人からの投稿だったとして、ぜひ参考にしたい技術は、
* 同時に複数のＩＰから投稿する
* gmailアカウントを複数使って投稿する

ってところか、あ。よく考えたら例えば、複数のプロキシを用意してバラバラで経由して投稿したらいけるか。なるほど。
gmailもよく考えたら別名アカウントを作成したら１つのgmailのアカウントで用意できるか。

なるほど！イケそうな気がしてきた！勉強になるなぁ。

次のコメントが楽しみだ。
entrykitについて

entrykitは、コンテナ実行時にテンプレートファイルをレンダリングしたり、起動コマンドを切り替えることができる。

## entrykitの使い方

Dockerfileで以下のように設定する。

1. entrykitをインストール
2. テンプレファイルをコンテナにコピー
3. ENTRYPOINTでコマンドの設定する

ENTRYPOINTは、["コマンド", "パラメータ1", "パラメータ2"]を定義する。

## entrykitの機能
entrykitの機能をまとめました。

- レンダリング
- コマンドの切替

それぞれ詳しく解説します。

### render機能
コンテナ実行時に環境変数の値を指定することで、テンプレートファイルをレンダリングすることができる機能。

例えば、nginxの設定でnginx.conf.tmplファイルをレンダリングするなら、以下のように設定する。
```
worker_processes {{ var "WORKER_PROCESSES" | default "1"}}
```
※デフォルト値は設定しなくても問題ない。

この環境変数のレンダリングは、Dockerfileをビルドした後に、以下のコマンドを実行する。
```
docker run -it -p 80:80 -e WORKER_PROCESSES=変更したい値 イメージ名
```

### switch機能
ENTRYPOINTで定義したコマンドを切り替える事ができる。

例えば、ENTRYPOINT ["switch", "A=コマンド1", "B=コマンド2", "コマンド3"]のように設定し、$docker runを場合。

- 通常起動＝コマンド3が実行。
- イメージ名 Bを指定=コマンド2を実行。
- イメージ名 Cを指定=コマンド1を実行。

自由にコマンドを選択することが可能になる。

### prehook機能
メインプロセス起動前のコマンドを設定できる。

ENTRYPOINT、["prehook", "パラメータ1", "パラメータ2"]

### codep機能
複数プロセスを同時起動することができる。

例えば、シェルスクリプトAとBが存在すると、以下のようなコマンドで同時に実行できる。

ENTRYPOINT、["codep", "シェルA", "シェルB"]
S3 バッチオペレーション 個人的概要

　S3バッチオペレーションについて使い方や使う場合がわからなかったので調べました。
自分の気になった点のみ記載しているので詳しく知りたい方は公式ドキュメント及び記事内のURLを参照。

[目次]
・できること
・設定方法
・料金
・その他
・個人的Q＆A

[用語]
・ジョブ
　S3バッチの基本単位。どのオブジェクトをバッチ処理するか、処理の方法などの設定が含まれている。
・オペレーション
　処理の方法。Lambdaを呼び出すのかタグを置き換えるのか、削除するのか等。


# できること
　オブジェクトやタグの処理を一括して処理したい時に使う。大量のオブジェクトも素早く処理。
　具体的には

1. Lambda関数の呼び出し
2. 全てのオブジェクトタグを置換する
3. 全てのオブジェクトタグを削除する
4. ACLを置換する
5. オブジェクトの復元
6. オブジェクトロックの保持
7. オブジェクトロックのリーガルホールド

　それぞれのオペレーションには個別のIAMロールやアクセス許可が必要となります。具体的にはLambdaを呼び出す場合にはLambdaに"s3:GetObject"等が必要で、オブジェクトのタグを置換する場合にはアクセス権限として[PutObjectTagging]が必要となる。

> [Amazon S3 バッチ操作に対するアクセス許可の付与](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/batch-ops-iam-role-policies.html)
> [S3 バッチ操作でサポートされるオペレーション](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/batch-ops-operations.html)

### 気になりポイント
**1. Lambda関数の呼び出し**
　オブジェクトをまとめて別のサービスで処理したい場合に使う。下記はS3に保存した動画ファイルをMediaConvertで様々な形式に変換して再度S3に保存するというケース。
![スクリーンショット 2022-08-06 9.32.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778864/f6272e16-2fde-1c30-6d0c-60cd4ea0ab48.png)

> [バッチトランスコーディング動画](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/tutorial-s3-batchops-lambda-mediaconvert-video.html)

**2. 全てのオブジェクトタグを置換する**
**3. 全てのオブジェクトタグを削除する**
　特になし

**4. ACLを置換する**
・該当するオブジェクトを操作する人物やその人物が実行できるアクションを一括で変えたい場合に使う。
・S3へのパブリックアクセスのブロックについてはバッチ処理ではなくコンソールで行う。
・ACLを無効(バケット所有者の強制設定)にしている場合は他のAWSアカウントやグループへの許可はできない。

> [アクセスコントロールリストを置き換える
](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/batch-ops-put-object-acl.html)

**5. オブジェクトの復元**
　Glacier Flexible Retrieval, Glicier Deep Archive及びIntelligent-TieringのDeep Archive層のオブジェクトを高頻度のストレージ層に戻す。アーカイブの取り出し方法(迅速、Standard, 大容量)を指定可能。
・ExpirationInDays
　復元が完了したオブジェクトの一時的なコピーを保持する期間。**Intelligent-Tieringでの復元を行う場合に指定すると復元リクエストが失敗する。**

> [オブジェクトの復元
](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/batch-ops-initiate-restore-object.html)

**6. オブジェクトロックの保持**
**7. オブジェクトロックのリーガルホールド**
　特になし


# 設定の流れ
　大まかな流れ

・マニフェストの準備(S3インベントリレポートもしくは自前のCSVファイル)
・アクセス許可の付与(必要なIAMロール、IAMポリシーの作成)
・マニフェストの指定
・オペレーションの選択

　マニフェストとは対象となるオブジェクトのリストです。S3インベントリポートで作成した場合はjson形式となります。CSVファイルとして用意することも可能です。

:::note warn
S3インベントリレポートについて
　最初のレポートが配信されるまでに最大で48時間かかることがあるので事前にインベントリ設定を行うこと。
:::

　S3インベントリレポートを指定してマニフェストからジョブを作成する場合は、S3のインベントリ設定から設定可能。
　{S3 >> バケットクリック >> 管理 >> インベントリ設定 >> マニフェストからジョブの作成}

> [Amazon S3 インベントリの設定](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/configure-inventory.html)


# 料金
・ジョブあたり　0.25USD
・実行された100万オブジェクトオペレーションあたり　1.00USD
・その他データ転送、リクエストなどはS3の料金を参照

> [Amazon S3 の料金 >> 管理と分析 >> S3 バッチオペレーションの料金](https://aws.amazon.com/jp/s3/pricing/)


# その他
・ジョブの優先度の設定可能
・CLIを使ってジョブのリストや詳細の取得が可能
・ジョブの完了レポートをリクエストすることができジョブのステータスや失敗の追跡が可能
・ジョブにタグ付け可能

> [S3 バッチ操作ジョブの管理](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/batch-ops-managing-jobs.html)
> [ジョブステータスと完了レポートの追跡](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/batch-ops-job-status.html)
> [タグを使用したアクセスのコントロールとジョブのラベル付け](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/batch-ops.html)


# 個人的Q＆A
Q. ジョブの自動化方法は？
　そもそも複数回処理を行うための機能ではないのでは？ AWS BatchならEventBridgeと統合して自動化が可能。
Multi-stage buildsでDockerfileをスッキリさせる

Multi-stage buildsで、Dockerファイルがスッキリするらしい。

## Multi-stage buildsとは
- FROMイメージ間のファイルを参照できる。(COPY --from)
- ASで中間イメージに名前を付けられる。

例えば、こんな感じです。
```
FROM ruby:alpine AS name
（省略）

FROM busybox
COPY --from=name <コピー元> <コピー先>
```
１つ目のFROMにAS nameで名前をつけることで、2つ目のFROMで--from=nameを使って参照できるようになる。

### Multi-stage buildsの利用法
1. Dockerfileを用意
2. FROMを複数定義
3. コピー元を定義

具体的には、●●=nameを定義し、別のビルドステージでCOPY --from=nameと指定することで直接参照が可能。

他には、FROM イメージ AS nameのように定義すると、ビルドステージに対してCOPY --from=nameが使えるようになる。

#### ビルドステージの指定もできる
さらに便利な活用法として、ビルドステージの指定も可能。

例えば、FROM イメージ AS builderという名前を付けていた場合は、以下のようなコマンドでビルドステージが指定できる。
```
 docker build --target builder -t イメージ .
```
RailsアプリをEKS on Fargate環境で構築

RailsアプリをEKS on Fargateで構築する際に調べた事まとめ
## Railsアプリを公開するには
EKS on Fargate構築では、AWS Load Balancer Controllerを使用することでアプリを公開することができるが、以下のようなデメリットが存在する。

- クラスタの再構築時にコントローラー等の設定を再度する必要がある。
- Terraformを使ってAWS Load Balancer Controllerを構築することができない。

クラスタを再構築しないのであれば問題ないかもしれないですが、やや気になるポイントだと思います。

### ノードグループを作成する
本来であればノードは全てFargateに任せたいところですが、今回はCoreDNSデプロイメントの設定変更を回避するために、一部ノードグループを作成しました。

CoreDNSとは、EKSクラスターのDNSサーバー(kubernetes推奨)。

coreDNSに問題があると、DNSが500エラーコードを返すこともある。

※ノードグループを用意したくない場合は、EKSクラスターを構築したあとに、以下のコマンドを打てばCoreDNSをFargateのみで使えます。
```
kubectl patch deployment coredns \
    -n kube-system \
    --type json \
    -p='[{"op": "remove", "path": "/spec/template/metadata/annotations/eks.amazonaws.com~1compute-type"}]'
```

```
kubectl rollout restart -n kube-system deployments/coredns
```
## RDSの設定

### RDSの環境変数
```
apiVersion: v1
kind: ConfigMap
metadata:
  name: rails-environent
data:
  RAILS_ENV: production
  APP_DATABASE_DATABASE: ✳︎✳︎✳︎_production 
  RAILS_SERVE_STATIC_FILES: "true"
  APP_DATABASE_HOST: terraform-✳︎✳︎✳︎✳︎✳︎✳︎✳︎.ap-northeast-1.rds.amazonaws.com #毎回値が変わるのでAWSで確認
  APP_DATABASE_USERNAME: admin
  APP_DATABASE_PASSWORD: ✳︎✳︎✳︎✳︎✳︎✳︎✳︎✳︎
```
RAILS_SERVE_STATIC_FILESをtrueにすることで、rails assets:precompileでpublicフォルダから静的ファイルの提供が行われるようになります。

Railsアプリのconfig/environment/production.rb内に以下のようなコードがあり、RAILS_SERVE_STATIC_FILESの値を使用しています。

```
config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present?
```

### OICDプロバイダー
EKSでは、pod単位でserviceaccountをIAMを割り当てることが出来る。

その際に、OICDプロバイダーが必要になるので設定が必要。
※OICDプロバイダー=なりすまし防止の認証機能のようなもの。

## 実際に生じたエラーと解決策まとめ
僕がRailsアプリをEKS on Fargate環境にデプロイする際に、実際に生じたエラーとその解決策を以下にまとめます。

## RailsコンテナがCrashLoopBackOffのまま立ち上がらない
原因が不明なのでログを出力して探る。
```
kubectl describe pod <ポッド名>
```
```
kubectl logs <ポッド名>
```
クラッシュする前のpodのログをみるには、--previousオプションを指定する。
```
kubectl logs --previous  <ポッド名>
```
### webidentityerrエラーでALBが作成されない
Ingressのapply後に、本来ならALBが作成されるハズなので、下記コマンドで確認するけれどALBが作成されない問題。
```
kubectl get ingress
```
NAME/CLASS/HOSTは表示されるが、ADDRESSの部分が空欄になっているので、ALBが作成されていないことが分かる。
```
NAME     CLASS               HOSTS                            ADDRESS         PORTS   AGE
alb-lb   alb-ingress-class   eks.mydogfoodnavi.com                               80      19s
```
原因がわからないので、とりあえずログを確認することに。

まずは、$ kubectl get podでAWSロードバランサーコントローラーのpod名を調べる。

続いて、$ kubectl logs <AWSロードバランサーコントローラーのpod名>でログを出力すると、以下のような怪しい文章を発見。
```
{"level":"error","ts":✳︎✳︎✳︎✳︎✳︎✳︎,"logger":"controller-runtime.manager.controller.ingress","msg":"Reconciler error","name":"alb-lb","namespace":"default","error":"WebIdentityErr: failed to retrieve credentials\ncaused by: AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentity\n\tstatus code: 403, request id: ✳︎✳︎✳︎✳︎✳︎✳︎"}
```

WebIdentityErrが何なのか分からないのでググってみると、以下のような原因が考えられることが判明。

- サービスアカウントの設定ミス。
- IAMロールの信頼関係の設定ミス。

自分の場合は、terraformのコードが間違っていて、正しくIAMロールを設定できていなかったので修正したら治りました。
Windows11にアップデートしたら有線でインターネットにつながらなくなった

表題の通り、アプデ後に無線ではつながるのに有線でインターネットにつながらないという事態になった。

同じトラブルに合う人もいるかもしれないので解決策を記す。


# 解決策: Win11用のイーサネットネットワークアダプタードライバーをインストール

参考記事には「イーサネット ネットワーク アダプター ドライバーをアンインストールして再起動します。」とあったが、自分のPCのイーサネットネットワークアダプター　ドライバーのWin11用をインストールすることで解決した。

# 手順

コントロールパネル>デバイスマネージャー>ネットワークアダプター

から自分のPCで使用されているアダプターの名前を確認。(参考: 著者は Realtek PCIe GdE Family Controller)

アダプターの名前でGoogle検索なりでWin11版のインストーラーを探し、ダウンロードして実行。

# ハマった点
LANケーブルの取り換えや、モデム、ルーターの再起動では解決しなかった。
ドライバーの自動更新では最新版をインストール済みとでていたので手動で探す必要があった。

------
参考URL: https://support.microsoft.com/ja-jp/windows/windows-%E3%81%AE%E3%82%A4%E3%83%BC%E3%82%B5%E3%83%8D%E3%83%83%E3%83%88%E6%8E%A5%E7%B6%9A%E3%81%AE%E5%95%8F%E9%A1%8C%E3%82%92%E4%BF%AE%E6%AD%A3%E3%81%99%E3%82%8B-2311254e-cab8-42d6-90f3-cb0b9f63645f
雀魂の拼音（ピンイン）

[雀魂の API など](https://wikiwiki.jp/majsoul-api/API%E4%B8%80%E8%A6%A7%E3%81%AB%E3%82%83)に使われている拼音（ピンイン）と漢字の対応をまとめました。



# 麻雀用語

## 役

ピンイン|漢字|備考
---|---|---
fu|符
yi|役
fan|飜
fanshu|飜数
fanfu|飜縛|飜縛り
xuanshang|懸賞|→懸賞役
baopai|宝牌|ドラ
chibaopai|赤宝牌|赤ドラ
biao|表|→表ドラ
li|裏|→裏ドラ
guyi|古役|ローカル役
shiduan|食断|喰いタン
manguan|満貫|→流し満貫
tiaoman|跳満
beiman|倍満|→三倍満
yiman|役満|→数え役満、二倍役満
leijiyiman|累計役満|数え役満
liujumanguan|流局満貫|流し満貫
liuman|流満|流し満貫
qianggang|槍槓
yifa|一発



## プレイヤーの操作

ピンイン|漢字|備考
---|---|---
chi|吃|チー
peng|碰|ポン
gang|槓|カン
rong|栄|ロン
lizhi / liqi|立直
zimo|自摸
fulu|副露
moqie|模切|ツモ切り
hule / hele|和了|→三家和了
angang|暗槓
minggang|明槓
babei|抜北|北抜き
jiuzhongjiupai|九種九牌
sigangsanle|四槓散了
sijializhi|四家立直
sifenglianda|四風連打
sanjiahule|三家和了|トリロン


## ルール

ピンイン|漢字|備考
---|---|---
sirendong|四人東
sirennan|四人南
sanrendong|三人東
sanrennan|三人南
ben|本|本場
chang|場|→東場、南場
bao|包
liqibang|立直棒
zhenting|振聴
shoupai|手牌
fafu|罰符
tianbian|天辺
changbang|場棒|積み棒
jifei|擊飛|トビ
liuju|流局|→流し満貫
toutiao|頭跳|頭ハネ
qieshang|切上|→切り上げ満貫
nanru|南入
xiru|西入
fandian|返点|1位必要点数
zimosun|自摸損|ツモ損
jingsuanyuandian|精算原点


## その他

ピンイン|漢字|備考
---|---|---
ju|局
xun|巡
ming|鳴
hu / he|和
fangchong|放銃
tingpai|聴牌
zhongju|終局
paipu|牌譜
paishan|牌山
peipai|配牌|→配牌公開
huangpai|荒牌
lianzhuang|連荘
paopai|砲牌|放銃牌
dadian|打点
shunwei|順位
changci|場次|対戦数
beizimo|被自摸|被ツモ
hupai|和牌
shaoji|焼鶏|焼き鳥（横移動）



# 雀魂用語

## 段位・部屋

ピンイン|漢字|備考
---|---|---
duanwei|段位
chuxin|初心
queshi|雀士
quejie|雀傑
quehao|雀豪
quesheng|雀聖
huntian|魂天
tongzhijian|銅之間|銅の間
yinzhijian|銀之間|銀の間
jinzhijian|金之間|金の間
yuzhijian|玉之間|玉の間
wangzuo|王座
yibanchang|一般場|段位戦
bisai|比賽|大会
dajiangsai|大獎賽|大会
yourenfang|友人房|友人戦の部屋
xiuxian|休閒|交流の間（休閒普通場）


## イベント・特殊ルール

ピンイン|漢字|備考
---|---|---
xiuluo|修羅|→修羅の戦
anye|闇夜|→闇夜の戦
mingjing|明鏡|→明鏡の戦
luandou|乱闘|→乱闘の間
shilian|試練|→試練の道
chuanma|川麻|赤血の戦（四川血戦麻将）
chiyu|赤羽|赤血の戦
jiuchao|鷲巣|明鏡の戦
huanjing|幻境|幻界の戦
hesu|合宿|温泉合宿 [^hesu]
kuangdu|狂賭|賭ケグルイ [^kuangdu]
doupai|闘牌|アカギ [^doupai]
huiye|輝夜|かぐや様は告らせたい [^huiye]
jjc|競技場|龍闘虎争
longzhimuyu|龍之目玉|龍の割目
xuezhandaodi|血戦到底|修羅の戦
anpai|闇牌
suoding|鎖定|闇維持
huansanzhang|換三張|牌交換
dingque|定缺|赤血の戦　不要な牌の種類


## その他

ピンイン|漢字|備考
---|---|---
jiuji|救済|復活コイン
yueka|月卡|開運御守
pifuquan|皮膚券 [^pifuquan]|着せ替え券
zhp|雑貨品|雑貨
bianjietishi|便捷提示|便利表示
dianfengduijue|巔峰対決|頂上対決
lianda|連打|同じ牌を連続に捨てた時
teshu|特殊|スペシャル
yuyin|語音|ボイス
shaizi|色子|サイコロ
pipei|匹配|マッチング
moshi|模式|ゲームモード
jushu|局数|友人戦の設定
qishidianshu|起始点数|初期点数
gaojishezhi|高級設置|詳細設定
xinshouyindao|新手引導|チュートリアル
zhuangban|装扮|装飾
xieyi|協議|合意
dongtai|動態|動作
kaiguan|開關|スイッチ
yulan|予覧|プレビュー
tanfang|探訪|読み込み中


# 漢字表記に変換する方法

https://translate.google.co.jp/?hl=ja&sl=zh-CN&tl=ja

Google 翻訳にピンインを手入力すると、漢字表記の候補が表示されます。基本的に麻雀用語でなければ、この機能だけを使って変換することが可能です。



[^hesu]: [イベント『温泉合宿』（修羅の戦）](https://twitter.com/mahjongsoul_jp/status/1349997601601454082)

[^kuangdu]: [イベント『修学淵林』（赤血の戦）](https://twitter.com/MahjongSoul_JP/status/1385216825206534145)

[^doupai]: [イベント『伝説の夜』（明鏡の戦 / 闇夜の戦）](https://twitter.com/MahjongSoul_JP/status/1453647727607226368)

[^huiye]: [イベント『恋の戦争』（幻界の戦）](https://twitter.com/MahjongSoul_JP/status/1519507946715201536)

[^pifuquan]: 皮膚 のほかに 服飾 や 外観 とも表記されます。
日本の小規模Webシステムが、PHP（Laravel）で開発するのが多い理由

# １．小規模の場合レンタルサーバを使うことが多い

小さい企業の場合、AWSやVPSよりレンタルサーバを使うことが多いです。
日本のレンタルサーバは、Node.jsは使えない所が多く、Ruby、Python、PHPが選択対象の言語になります。
特に、PHPは新しいバージョンへの対応も比較的早く、サポートが手厚いです。
これが言語選定において大きく寄与していると思います。

https://speever.jp/useful/how-to-choose-rentalserver-php/


# ２．レンタルサーバで使われるライブラリ

Webサイトをプログラムわからないひとでも更新したいというニーズを満たすために、WordPressが使われることが多いです。
レンタルサーバの場合、WordPressを簡単にインストールする機能が管理画面についていたりするので、よく使われます。
もちろん、WordPressはPHPで作られていますので、カスタマイズをするときもPHPが使われます。

https://webst8.com/blog/wordpress-recommend-rental-server/

もう一つは、2022年時点でPHPでWebアプリを開発するとき、Laravelを使うのがデファクトスタンダードになっています。
それはRailsライクな開発ができること、情報やいろいろな機能を満たすサードパーティライブラリも多いことが挙げられます。


https://www.anken-navi.jp/news/programming-language/php/php-framework-trends/


Laravelは帳票周りのライブラリ、情報も多くあり、業務案件で使うには悩みや問題が比較的少ないライブラリです。


# ３．言語の利用数や特徴

PHPは、世界的にみるとかなりシェアがあります。おそらく日本でも案件数はJavaには劣るかもしれませんが、
RubyやPythonよりは多いでしょう。

https://webtan.impress.co.jp/u/2021/06/13/40499


ちなみに、最近は、PythonのフレームワークDjangoもシェアを伸ばしています。Pythonの知名度があがり、大学での利用が増えていることも一つの要員かもしれません。

https://integraldx.info/php-ruby-python-10780


一時期、型がない言語が簡単でよいといわれていましたが、最近は逆に、チーム開発が増え、
IDEを使うのが一般化してきたこともあり、型がある言語がコードの安全性やコーディングの生産性を高める理由で、
採用される事が多いです。

もともとPHPは型がなかったのですが、PHP7や8では型を使うことができます。
RubyやPythonよりは型の仕組みはしっかりしているように見えます。

https://tatsuno-system.co.jp/2021/03/02/blog_php-program/


こうしたユーザー数や言語的な特徴もPHPが採用される理由になっていると思います。

# ４．Livewireなど脱JSでのフロント開発

PHPを利用する際に、できればフロントエンドもPHPで書きたいというニーズはあると思います。
Laravelでは、Livewiereをつかうことで、PHP側でフロントエンドのコンポーネントやモデルを書くことができます。

こうすることで、言語を分けることが減るので、プログラマーのストレスは少なくなりますし、コードリーディングもしやすくなります。
この点も、PHPで開発することを後押しすると思います。

もちろん、RubyでもHotwireの仕組みがありますので同様のことはできます。
Node.js以外の言語の脱JSという流れは、徐々にみられます。


https://b3s.be-s.co.jp/programming-language/php/4599/


# ５．最後に

あくまでもポエムの体で記事を書きました。
レンタルサーバは手間も少なく、安いので小さい企業では採用されることが多いです。
そこで最もつかわれるのがPHPである以上、どうしてもPHPの採用は減らないと思います。

また、Livewireのように脱JSという生産性を上げる仕組みもできているので、
ますますPHPの人気は衰えないように思います。

ちなみに、大規模開発でPHPが使われてないとはいっていません。
大規模で使われていることもあります。ただ、大規模開発の場合、Java(SpringBoot）、Scala、C#（.NET)、Ruby（Rails）、Goなども使われているのをみるので、PHPが突出して多いとは思わなかったので、大規模開発については触れていません。
Rails✖︎Webpacker

Webpackerとは、webpackをRailsで使用するためのgemパッケージ。

webpackを使用すれば、Javascriptなどの静的アセット(リクエスト毎に生成しないもの)の管理&packにまとめる等が出来る。

※静的アセットを利用することで、アプリケーションの高速化につながる。

## WebpackerをRailsで使うには
1. YarnとNode.jsを用意。
2. Webpackerをインストール。

### Webpackerインストール後
Webpackerのインストール後は、app/javascript/packs以下のJavascriptファイルがコンパイルされてpackにまとめられるようになる。

packにまとめられたコードは、以下のようなコードで呼び出すことが出来る。

```
<%= javascript_pack_tag 'hello_vue' %>
```
※自分の場合は、packsディレクトリにhello_vue.jsというファイルが存在するので、'hello_vue'を指定している。

### コンパイルする方法
```
rails assets:precompile
```
上記コマンドを実行すれば、publicディレクトリの配下にコンパイルされたJavaScriptのコードなどが出力される。

また、同時に生成されるmanifest.jsonというファイル内で定義されたファイルが出力されるよういなっている。
```
{
  "entrypoints": {
    "hello_vue": {
      "js": [
        "/packs/js/✳︎✳︎✳︎-✳︎✳︎✳︎.js"
      ],
      "js.map": [
        "/packs/js/✳︎✳︎✳︎-✳︎✳︎✳︎.js.map"
      ]
    }
  },
  "hello_vue.js": "/packs/js/✳︎✳︎✳︎-✳︎✳︎✳︎.js",
  "hello_vue.js.map": "/packs/js/✳︎✳︎✳︎-✳︎✳︎✳︎.map"
}
```
上記コマンドを実行時には、NODE_ENVのデフォルトはproductionになる。

### WebpackerでJavaScriptの環境変数を扱うには
Railsで開発を行うさいに、Wecpackerで扱うJavaScriptの環境変数を切り替える方法を調べたのでまとめます。

1. gem dotenvを入れる。
2. envファイルを環境ごとに作成。
3. package.jsonにScriptsを記載。
4. webpack/environment.jsにコードを追加。

上記の流れの詳細は以下の通り。

#### gem dotenvを入れる
gemfileに、以下のコードを追加。
```
gem 'dotenv'
```
bundle installでgemをインストールする。

#### envファイルを環境ごとに作成
自分が作成したファイルは、以下の2パターンです。
```
(.env.development)
NODE_ENV='development'
VUE_APP_API_ORIGIN='http://localhost:3000'
```
```
(.env.production)
NODE_ENV='production'
VUE_APP_API_ORIGIN='https://example.com'
```
同じ名前の環境変数を定義していますが、NODE_ENVの値によって開発or本番環境用の値を取り出します。

#### package.jsonにscriptsを記載
以下のコードは、[こちら](URL "https://zenn.dev/atsushi101011/articles/60f2e01ebe2e94")
のページで紹介されていたものを使用しました。
```
"scripts": {
    "serve": "vue-cli-service serve",
    "dev-serve": "vue-cli-service serve --mode development",
    "prod-serve": "vue-cli-service serve --mode producution",
    "build": "vue-cli-service build",
    "dev-build": "vue-cli-service build --mode development",
    "prod-build": "vue-cli-service build --mode producution",
    ...
  }
```
#### webpack/environment.jsにコードを追加
dotenvを使用できるようにするためのコード。
```
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
const dotenv = require('dotenv')

const dotenvFiles = [
    `.env.${process.env.NODE_ENV}.local`,
    '.env.local',
    `.env.${process.env.NODE_ENV}`,
    '.env'
  ]
  dotenvFiles.forEach((dotenvFile) => {
    dotenv.config({ path: dotenvFile, silent: true })
  })
  
  environment.plugins.prepend('Environment',
    new webpack.EnvironmentPlugin(
      JSON.parse(JSON.stringify(process.env))
    )
  )


module.exports = environment
```
サーバを立て直した後、ssh接続できなくなった

### はじめに
サーバーを立て直した際に、フィンガプリントが異なるということでssh接続が出来なくなったため、記事にまとめました。

フィンガープリントとは、指紋のようなものです。
以下のサイトが参考になりました。
https://www.videor.co.jp/digestplus/market/2021/02/41277.html

初めてSSH接続したサーバーの場合、フィンガープリントが「/home/ユーザ名/.ssh/known_hosts」ファイルに記録されます。
次回、同じIPアドレスのサーバーでssh接続する場合は、フィンガープリントが一致しているかチェックされます。

前回投稿した以下の記事に、フィンガープリントについて記載したため参考にしてください
https://qiita.com/gama1234/items/3ad5f698784af3fd39d1


### エラーの内容
前回のIPアドレスを使用して、サーバーを立て直した際にフィンガープリントが変わることにより、
SSH接続した際に、以下のエラーが出てssh接続出来ませんでした。
```
test@DESKTOP-0S2U0NI:~$ ssh 192.168.0.3
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:4IzCPtqvmBKGorb9UGdSOXMOBt1MyoH6akql4Ck10mk.
Please contact your system administrator.
Add correct host key in /home/test/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/test/.ssh/known_hosts:2
  remove with:
  ssh-keygen -f "/home/test/.ssh/known_hosts" -R "192.168.0.3"
ECDSA host key for 192.168.0.3 has changed and you have requested strict checking.
Host key verification failed.
```

### 解決方法
本課題のエラーの対応方法は、以下のQiitaの記事が参考になりました。有難うございました。
https://qiita.com/hnw/items/0eeee62ce403b8d6a23c

ssh-keygen -Rのコマンドは、指定したホストに属する鍵を全て取り除く様です。
以下のサイトを参考にしました。
https://atmarkit.itmedia.co.jp/ait/articles/1908/02/news015.html

「ssh-keygen -R ipアドレス」を実行し、ホストに属する鍵を全て取り除きました。
```
test@DESKTOP-0S2U0NI:~/.ssh$ ssh-keygen -R 192.168.0.3
# Host 192.168.0.3 found: line 2
/home/test/.ssh/known_hosts updated.
Original contents retained as /home/test/.ssh/known_hosts.old
```
問題なくSSH接続出来ました。
```
test@DESKTOP-0S2U0NI:~/.ssh$ ssh root@192.168.0.3
The authenticity of host '192.168.0.3 (192.168.0.3)' can't be established.
ECDSA key fingerprint is SHA256:4IzCPtqvmBKGorb9UGdSOXMOBt1MyoH6akql4Ck10mk.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.0.3' (ECDSA) to the list of known hosts.
root@192.168.0.3's password:
Last login: Sat Aug  6 10:35:48 2022
```
### まとめ
実業務でサーバーの移行により、IPアドレスが同じでサーバーが異なる際に本課題のエラーが出ました。
事前に知識として対応方法を知ることで、業務で役に立つと思いました。
Nginxの設定

## Nginxについて調べたこと殴り書き
### location{}=URIのパス毎の設定
リクエストURIのパスが、locationディレクティブのパス条件に一致した場合、設定が適応される。
※@は名前付きロケーション
パスの代わりに、unicornのように名前を付け、名前付きロケーションを作ることができる。内部リダイレクトで利用できる。

### try_files
存在をチェックするファイルやディレクトリと存在しなかったときにリダイレクトするURIのパスを指定
- try_files ファイル ... パス;
- try_files ファイル... =コード;
指定したファイルやディレクトリの存在を順に調べ、存在すればそのファイルやディレクトリに対応したファイルを返す。
１つも存在しなかったら、最後に記述したパスに内部リダイレクトさせる。
パスの代わりに名前付きロケーションを設定することもできる。

### upstream
Nginxをひとまとまりのサーバーと一緒に使うためにグループを定義する

### server
listen 使用するIPやポートを指定
server_name ホスト名
root ドキュメントルートを指定
location 任意のURIごとに異なる設定をするためのもの /なら全部
cscの作法 その262

# 概要
cscの作法、調べてみた。
インストーラーやってみたいので、wixいれてみた。

# 環境

windows10

# インストール

- wix310.exeをダウンロードして実行
- Wix Toolsetと立ち上がるのでInstallボタンを押す

# サンプルコード

```
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
	<Product
		Id="a52608a3-9a98-4a25-9c9c-209bc5e72f70"
		UpgradeCode="a52608a3-9a98-4a25-9c9c-209bc5e72f70"
		Name="TEST PRODUCT"
		Version="1.00.0000"
		Manufacturer="ohisama"
		Language="1041"
	>
		<Package Id="*" Compressed="yes" InstallerVersion="400" />
	</Product>
</Wix>

```

# コンパイル手順

```
>set PATH=C:\Program Files (x86)\WiX Toolset v3.10\bin;%PATH%

>candle test0.wxs

>light test0.wixobj

```

以上
CI/CDパイプラインの構築

## CI/CDパイプラインとは？
CI/CDパイプラインは、2つの要素で構成される。

- CI(継続的インテグレーション)
- CD(継続的デリバリー)

それぞれ詳しく説明すると、以下のような感じ。

### CI(継続的インテグレーション)

継続的インテグレーションは、コードを変更した際のビルド⇨テストの流れを自動化する仕組みのこと。

また、CIを導入していれば、コードを短期間中に複数回マージすることで、エラーを引き起こすコードの判別がしやすくなる。

### CD(継続的デリバリー)
継続的デリバリーは、継続的インテグレーションを拡張したもので、コードを変更した際に、自動で本番環境へリリースを行えるように準備する仕組み。

同じ略称「CD:継続的デプロイ」は、ビルドやテスト後のプログラムを自動で本番環境へ導入させること。

### CI/CDパイプラインの流れ
Ci/CDパイプラインは、以下のような流れを自動化したもの。

- 解析
- ビルド
- テスト
- デプロイ

簡単に言えば、コードを変更してGitHubなどへpushしたら、自動でビルドやテストをし、デプロイまで済ませる仕組み。

## なぜCI/CDパイプラインが必要なのか？
CI/CDパイプラインの必要性を理解するには、以下の要素について知る必要がある。

- アジャイル
- DevOps

それぞれの詳細を以下にまとめた。

### アジャイルとは？
アジャイルは、システムを小さく区切って、細かく開発とテストを繰り返していく考え方。

一度開発の方針を決めたら後戻りすることがない、「ウォーターフォール型」の開発の欠点を補うため生まれたのがアジャイル。

「プロジェクトを進めていく中で、方向性が変わったりするのは仕方ないから、それに柔軟に対応できるようにしようねってのがアジャイルの考え方」

### DevOpsとは？
開発と運用が協力しあい、柔軟かつ迅速にプロジェクトを成長させるという考え方で、以下のような取り組みを行う。

- 作業の自動化
- リスクの軽減
- 開発と運用の連携
- その他(モニタリング、ログングなど)

上記の「作業の自動化」と「リスクの軽減」を行うのに、CI/CDパイプラインが必要となる。

#### 作業の自動化
例えば、コードを変更してリリースする場合、自動化を行うことで人為的ミスや作業時間の短縮を行える。

#### リスクの軽減
細かい変更でも頻回にコードをテスト&リリースすることで、エラーの修正やロールバックがしやすくなる。

1回の変更量が少ないので、どこが悪かったのか原因を見つけやすくなる。

## CI/CDパイプライン用のツール
CI/CDパイプラインを構築する際の選択肢。

- CircleCI
- CodeBuild
- Jenkins
- Travis CI
- GitHub Actions
- その他

それぞれの特徴を以下にまとめる。

### CircleCI
SaaS型サービスのデファクトスタンダード。

よく使用されていることもあり、情報量がおおく学習コストも低めである。

### CodeBuild
AWSのCIサービス。

単体ではCIサービスのみだが、CodePipelineなどを併用すれば、CI/CDパイプラインを構築できる。

AWSを使用するなら、連携しやすいので選択肢に入る。

### Jenkins
オンプレミス型のデファクトスタンダード。

オンプレミス型であり、自分で構築や管理を行なっていく必要があるので、運用コストが高くなる。

ただし、セキュリティ管理やマシンの性能などの選択肢の幅が広く、自由度は高い。

### Travis CI
オープンソースプロジェクトで無料で利用できる、SaaS型のCIサービス。

オープンソースとは、ソースが公開されたプロジェクトのことで、AndroidやWordPressなどが存在する。

自分の場合は、オープンソースプロジェクトを扱わないので、選択肢から外れる。

### GitHub Actions
GitHubのCI/CDサービス。

Qiitaで検索してみると意外と記事数がおおく、情報を得やすい。

### 最終的に自分が選択したツール
自分は、以下のポイントを重要視しCircleCIを選択した。

- シェア率が高い。
- 学習コストが低め。

就職した際に、職場で使われていそうなツールを選びたいので、シェア率は重要視した。

残念ながら、CIツールの実際のシェア率は分からなかったのだが、JenkinsやCircleCIはかなり使われているらしい。

しかし、Jenkinsは自分でデプロイサーバーを立てたり、運用管理する必要があるので候補から外した。

GitHub Actionsも情報量が多く、かなり使われてそうな感じがしたが、今回は歴史の深いCircleCIの方を選択。
WordPressのブログのRSSフィード

# 概要

- WordPressブログのRSSフィードURlの確認方法をまとめる。

# RSSフィードURL

- WordPressは複数のRSSフィードURLを勝手に作ってくれている。
- デフォルト状態で「WordPressブログが更新された時に通知するRSSフィードURL」は下記のようになる。
    - `https://サイトのURL/feed/`
- 例えば弊社の技術ブログが更新された時に通知するRSSフィードURLは下記になる。
    - [https://anteku.jp/blog/feed/](https://anteku.jp/blog/feed/)

# 参考文献

- [https://ja.wordpress.org/support/article/wordpress-feeds/](https://ja.wordpress.org/support/article/wordpress-feeds/)
【VBA小ネタ】ファイル名に使えない文字を回避する

いまさらなので、深く考えない
---
ファイル名やフォルダ名に使えない文字は9つ。リネーム時にそれらの文字を入力しようとするとWindowsが教えてくれる。
![ファイル名に使えない文字.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294209/bb16e370-dd8b-a269-1059-e4cba449fd03.png)
使えないのは半角文字なので、以下の全角文字に変換する。
| 全9種類 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 全角文字 | ￥ | ／ | ： | ＊ | ？ | ” | ＜ | ＞ | ｜ |

以下、超簡単な関数を作っておくと便利。
```vb:VBA
Public Function ReplaceStg(ByVal stg As String) As String
    stg = Replace(stg, "\", "￥")
    stg = Replace(stg, "/", "／")
    stg = Replace(stg, ":", "：")
    stg = Replace(stg, "*", "＊")
    stg = Replace(stg, "?", "？")
    stg = Replace(stg, """", Chr(&H8168)) ' VBAでは全角のダブルクォーテーションが打てない
    stg = Replace(stg, "<", "＜")
    stg = Replace(stg, ">", "＞")
    stg = Replace(stg, "|", "｜")
    ReplaceStg = stg
End Function
```
ついでに連番を振ってみる
---
この関数を使って、禁止文字を使ったフォルダを同じ場所に10個作ってみよう。
以下は指定したパスと名前で新しいフォルダを作る関数。既に同名のフォルダがあれば、連番を振る。

```vb:VBA
Public Sub MakeDirAddNumber(ByVal pth As String, ByVal dir As String)
    Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
    Dim pthDir As String: pthDir = pth & "\" & dir
    Dim fullNm As String: fullNm = pthDir
    Dim i As Long: i = 1
    Do While fso.FolderExists(fullNm)
        i = i + 1
        fullNm = pthDir & " (" & i & ")"
    Loop
    fso.CreateFolder fullNm
End Sub
```
これら2つの関数を組み合わせて、デスクトップ上に禁止文字でフォルダを10個作ってみる。

```vb:VBA
Private Sub Hoge()
    
    Dim dir As String: dir = ReplaceStg("\/:*?""<>|") ' 全ての禁止文字をぶち込む
    
    Dim wsh As Object: Set wsh = CreateObject("WScript.Shell")
    Dim pth As String: pth = wsh.SpecialFolders("Desktop")
    Dim i As Integer
    For i = 1 To 10
        MakeDirAddNumber pth, dir
    Next
End Sub
```

おまけ
---
ダブルクォーテーションについて調べた。
ダブルクォーテーションには開始と終了の2種類あるらしい。（Qiitaのフォントだとわかりずれーな:sweat_smile:）
#### 　　開始 [ “ ]  　　終了 [ ” ]


開始は、オタマジャクシの頭が下向き、終了は上向き、といった感じかな。

日本ではこの区別にあまり馴染みが無い。フォントにもよるが、半角は終了の方で表示される。全角であれば、両方ともメモ帳などで打てるが、VBAではエラーとなってしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294209/9815bd4e-6fed-45d1-4c33-6f7e4713bd14.png)
また、`"`でエスケープしようとすると全角から半角に変化してしまう。
なので、前述の`ReplaceStg`関数のように`Chr`関数で出力する。以下は16進数の文字コードを`Chr`関数に与えてみた。

```vb:VBA
Chr(&H22)   ' --->   "    半角の終了ダブルクォーテーション 
Chr(&H8167) ' --->   “    全角の開始ダブルクォーテーション  
Chr(&H8168) ' --->   ”    全角の終了ダブルクォーテーション
```
全角のダブルクォーテーションを両方とも打てると言ったが、開始の方は普通に変換しようとしても候補に出てこないぞ:interrobang:


#### `Alt`を押しながらテンキーで`0` `1` `4` `7`と打って`Alt`を放す

ググったら早速答えを見つけた。（何でも知ってる、ぐーぐるさん:clap::clap_tone1::clap_tone2::clap_tone3:）
しかし、テンキーが無いノートパソコンってどうやって打つんだろう。。。
ルーティングで'Target class [hoge] does not exist.'と怒られたときの対処法

`Laravel Framework 9.22.1`
マニュアルに沿い、Controllerを作成し、indexというアクションを追加、web.phpにルーティングを設定したら表記のエラーで怒られました。

# 最初にやった
`make:controller` コマンドで`HelloController`を作成
サンプルのアクションを記述し、ルート情報を設定したところ、表記のエラーに。
```web.php
Route::get('hello', 'HelloController@index');
```

# ためした①
エラーメッセージで検索したところ、Laravel 8以降からルーティングの書き方が変わっているとのことで、`Route::get` の表記を修正。
参考：https://teratail.com/questions/292482#reply-413765
```web.php
Route::get('hello', [HelloController::class, 'index']);
```
**→エラー解消せず！！:joy:**

# ためした②
さらにLaravel ⑧以降のルーティングの注意点として、
>ルート定義ファイル web.php の冒頭にルート定義で使用されているコントローラの名前空間をuseキーワードを使用して書く

とのこと。
参考：https://qiita.com/Masahiro111/items/6c9cde6c265a241439c4

追加したコントローラの名前空間を冒頭に追記。
```diff_php:web.php
<?php

use Illuminate\Support\Facades\Route;
+ use App\Http\Controllers\HelloController;
```
**→うごいた！！:joy:**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1974587/36a1136c-f571-1108-290a-938699aeeb70.png)

※念のため「ためした①」で直したRoute設定を修正前に戻し、「ためした②」の名前空間の追記はそのままにしてテストしてもエラーが出た

# まとめ
Laravel 8以降からルーティングの設定のしかたと、ルート定義のお作法が変わっている
- Routeの設定を以下の形式にすること
```web.php
Route::get('ページ名', [コントローラ名::class, 'アクション名']);
```
- web.phpの冒頭に使用したいコントローラの名前空間をuseキーワードを使用して書くこと
Macを買ってやったこと(2022 Apple Silicon編)

M2のMacBook Airをポチったので環境構築のメモ。
インストール作業がIntel Macに比べて体感爆速だった。
Intel MacでもRosettaのインストール以外は使えると思う

## GUIから

- Chrome
- Google Japanese Input
- Jetbrains Toolbox
- Visual Studio Code
- Nerd Font

この辺はBrewとかでもインストールできると思うけど、先にインストールしてしまう。

## App Storeから

- XCode

実行後ConsoleからlicenseにAgreeしておく。

## CLI

- Gitの初期設定

```shell
git config --global user.name "Your Name"
git config --global user.email "Your Address"
ssh-keygen -t ed25519
cat ~/.ssh/id_ed25519 | pbcopy # Githubなどに登録しておく
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k
softwareupdate --install-rosetta
```

## Homebrewから

開発まわりで使いそうなツールを入れていく

- dotnet
- Terraform
- JDK
- Helm
- Skaffold
- Dapr
- Go
- Node.js
- Github CLI

```shell
brew install zsh-completions
# Modify zshrc
source ~/.zshrc
rm -f ~/.zcompdump; compinit
brew install zsh-autosuggestions
brew install --cask docker
brew install --cask devtoys
brew install --cask corretto
brew install helm
brew install skaffold
brew install --cask dotnet-sdk
brew install mono-libgdiplus # https://docs.microsoft.com/en-us/dotnet/core/install/macos#libgdiplus
brew install terraform
brew install golang
brew install node
arch -arm64 brew install dapr/tap/dapr-cli
brew install gh
```

## ZSHRCのファイルの中身

```shell
```zsh
zstyle ":completion:*:commands" rehash 1

typeset -U path PATH
path=(
  /opt/homebrew/bin(N-/)
  /opt/homebrew/sbin(N-/)
  /usr/bin
  /usr/sbin
  /bin
  /sbin
  /usr/local/bin(N-/)
  /usr/local/sbin(N-/)
  /Library/Apple/usr/bin
  '/Users/narachannel/Library/Application Support/JetBrains/Toolbox/scripts'
)

export GOPATH=$HOME/go
export GOROOT="$(brew --prefix golang)/libexec"
export PATH="$PATH:${GOPATH}/bin:${GOROOT}/bin"
plugins=(git brew kubectl history-substring-search)

alias code="code-insiders"
alias k="kubectl"
alias python="python3"
alias pip="pip3"

ZSH_THEME="powerlevel10k/powerlevel10k"

#ZSH Autocomplete
if type brew &>/dev/null; then
  FPATH=$(brew --prefix)/share/zsh-completions:$FPATH
  source $(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh
  source <(kubectl completion zsh)
  autoload -Uz compinit
  compinit
fi
```

## 参考、はまった事とか

- Homebrewインストール後brewがpathに入らない -> [macOSのzshではこれだけはやっておこう](https://zenn.dev/sprout2000/articles/bd1fac2f3f83bc)
- VS Codeはここを見てPathを通しておく -> [Visual Studio Code on macOS](https://code.visualstudio.com/docs/setup/mac)
javascriptで大量要素をDOMツリーに追加するときはDocumentFragmentを使おう

# 前置き

レガシーなシステムを保守、パフォーマンス改善をするときにとんでもない実装がされていることってありますよね(悲)

今回は私が遭遇したとんでも実装を改善し、1/20程度の実行時間に改善できた話を紹介します。

# 実装内容

(実際の処理内容とは多少異なりますが、)APIで取得したデータ(リスト)を繰り返し処理し、テーブルに表示する実装を行います。

## もとの実装

https://jsfiddle.net/ez4hpLcv/17/

もとの実装ではhtml側でテンプレートを作っておき、それをループ処理でクローンし、正規表現で文字列を置換しながらひたすらDOMツリーに追加する方法で実装していました。
(実際に実装されていたものではもっと要素も多く、複雑な処理をしていたため、1万件表示しきれるまでに30～40秒程度かかっていました。上記JSFiddleで私の環境では10～12秒程度かかっています。)

## 改善後の実装

https://jsfiddle.net/5q3zuhkm/23/

改善後の実装では、[createDocumentFragment()](https://developer.mozilla.org/ja/docs/Web/API/Document/createDocumentFragment)で仮想的なDOMを作り、その仮想DOMに対して子を追加していき、ループ処理後にまとめて追加します。
(実際に実装されていたものを改善したものでは2～3秒、JSFiddle内では0.1～0.3秒程度に改善されました。)

# 備考

- 実際に実装されていたものと合わせてもとの処理で正規表現の文字列置換を行っていたため、そこが無くなったのも処理速度改善に繋がったのでは？と思い追加検証を行った結果以下の通りとなりました。
    - [クローンで追加](https://jsfiddle.net/pvsg9eyd/2/) ： 4～5秒
    - [DocumentFragmentを使う](https://jsfiddle.net/Ltq7p03s/1/) ： 0.1秒程度
- もとの処理ではhtml側で`onClick`を設定し、その引数に`_ID`を設定し、そこも置換して引数としたかったようです。
    - (動きはするけどなんかもどかしい・・・ｗ)

# 参考

https://uhyohyo.net/javascript/7_4.html

# 終わりに

このレガシーなシステムにはもとの処理と同じ方法でテーブルやリストを作る処理での実装がいくつも実装されていました。
おそらく最初に作った人がこの処理で実装し、その処理を真似ながら作ったことでどんどん遅い処理が増えて行くことになったのだと思います。

初期の実装段階から件数が多くてもまともに動くことを検証しながら実装していくことが大事なんだとおもいました。

もとの処理での実装で複数のテーブルを作り込む処理を実装しているページがあり、最初のローディングが終わるのに1,2分かかるといったこともあり、かなりのパフォーマンス改善になったので、今後も検証・改修を続けて行こうと思います。
Hexabase TypeScript SDKの使い方と認証を行う方法

[Hexabase](https://www.hexabase.com/)は企業においても安心して利用できるBaaS（Backend as a Service）を提供しています。多くのBaaSがそうであるように、主にフロントエンド開発者に利用してもらいたいと考えています。そこで現在、TypeScript SDKの開発が進められています。

[@hexabase/hexabase-js - npm](https://www.npmjs.com/package/@hexabase/hexabase-js)

この記事ではHexabase TypeScript SDKのインストールと、認証周りの使い方を紹介します。

## インストール

インストールはnpmやyarnを使って行います。

```
# npmの場合
npm install @hexabase/hexabase-js

# yarnの場合
yarn add @hexabase/hexabase-js
```

## インポート

インポートすると、 `HexabaseClient` というオブジェクトが取得できます。

```ts
import { HexabaseClient } from "@hexabase/hexabase-js";
```

## 初期化

HexabaseClientを初期化します。

```js
const client = new HexabaseClient();
```

### 認証

Hexabaseでは業務利用を想定しているため、利用する際に認証情報が必須になります。最初はメールアドレスとパスワードで認証し、その後はトークンを使ってGraphQLにアクセスします。 `client` を使って処理します。

初回の認証は次のようになります。

```ts
client.login({email, password, token});
```

| 引数名 | 必須 | 意味 |
|--------|--------|--------|
| email | △ | 認証するメールアドレス |
| password | △ | 認証するパスワード |
| token | △ | 認証した後取得できるトークン |

emailとpassword、またはtokenのどちらかが必須です。

## まとめ

Hexabase TypeScript SDKを使えば、VueやReactなどと連携したWebアプリを素早く開発できるようになります。2022年08月現在絶賛開発を進めていますので、ぜひ試していただいてフィードバックいただければ嬉しいです！

[hexabase/hexabase-js](https://github.com/hexabase/hexabase-js)
composerインストール時のphpコマンドエラー（Mac）

PHP Laravel学習のため、環境構築。
composerインストール時に下記エラーのため実行不可だった。

　
●実行しようとしたこと
composerをコマンドにてインストール

https://getcomposer.org/download/


　
●エラー内容
コマンド実行時、phpコマンドが見当たらないエラーが発生
```
% php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
zsh: command not found: php
```
　

●PC環境
・OS：Mac
・シェル：zsh
```　
% echo $SHELL
/bin/zsh
```

●解決
PATHを通すため、「.zshrc」を設定する必要があった。
・.zshrcをテキストエディターで開くコマンド
```
% open ~/.zshrc
```
・.zshrcに下記を追加し、保存する(今回：php7.4.21を追加)
```
export PATH=$PATH:/Applications/MAMP/bin/php/php7.4.21/bin
```
・ターミナルで設定を読み込む
```
% source ~/.zshrc 
```
・PATHの確認
→自分が通したいPATHが存在することを確認
```
% echo $PATH
```
　
その後、無事にcomposerをコマンドでインストールすることができました！
　

※composerインストールに参考した記事

https://snome.jp/framework/laravel-install-mac/
【夏休み企画】#IT用語一問一答【毎朝投稿3日目】GC

# この記事を読むと、、
- 「関連用語」を使って「GC」を説明できるようになる
- 「GC」がもっと好きになる(多分)

# 関連用語
memory leak / dangling pointer / stop-the-world GC / incremental GC / concurrent GC

[**復習用**] 記事の内容を見る前に上記の言葉でGCを説明してみよう！

# 企画説明
- クラウドって何？って人に聞かれて説明してるけど俺もよく知らないや、、
- ドキュメント読んでみてるけど半分くらい何言ってるか分かんない、、
- 今日の夕飯はナスの炒めものにしよっかな〜、あれ、NASってなんだっけ？

みたいなことが結構あったので、知ったかしていたIT用語を毎日一個ずつちゃんと学んでいこうっていう企画です！

昨日の記事はこちら↓

https://qiita.com/acta/items/a7b29ad455553b947d75

# GCとは
GC = Garbage Collection = プログラムが割当て、不要になったメモリ領域を自動で解放してくれる仕組み

- Lispにおけるメモリ管理を簡単にするために開発された
- 多くの高級言語では標準で実装されている
- C/C++ではライブラリを通してGCが使える

GCのおかげで以下のバグを回避できたりする
- **memory leak** = オブジェクトが存在するが、それを指すポインタがない状態
    - ただし、GCがあってもポインタを保持し続けるコードを書けばmemory leakしてしまう
    - メモリ不足の原因になる
- **dangling pointer** = 解放済みのオブジェクトを指すポインタ
    - dangling pointerがデリファレンスされた場合、意図しない挙動をしてしまう
- double free bug = 解放済みのメモリ領域を再度解放しようとすること

※GCには様々な実装方法があるけど、以下は最も一般的なtracing GCの話です

GCをするタイミングには以下のパターンがある
- **stop-the-world GC** = GC中にアプリケーションスレッドを完全に停止する方法
    - オブジェクトの新規割当てや解放が起きないため安全
    - heap全体のGC = full GCの際にアプリケーションがしばらく応答しない時間が発生する
    - 非対話形式のプログラムに向いている
- **incremental GC** = GCを複数回に分けて実行する方法
    - 全体で見ればstop-the-world GCよりも時間がかかる
- **concurrent GC** = アプリケーションスレッドと並行してGCを実行する方法
    - GCスレッドを同時に動作させる分、スループットが低下する
    - プログラムの実行を止めない

# 【おまけ】調べている時にでてきたなにこれ用語
- heap memory = プログラム実行時に動的に確保可能なメモリ領域
- throughput = 単位時間あたりの処理能力


# 参考資料
- https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)
- https://en.wikipedia.org/wiki/Tracing_garbage_collection
- https://docs.unity3d.com/Manual/performance-incremental-garbage-collection.html
- https://atmarkit.itmedia.co.jp/ait/articles/0704/24/news136.html
- https://en.wikipedia.org/wiki/Network_throughput