OmniAICreator/Qiita-1.07M huggingface dataset:
データベースのテーブル設計の要素

こんにちは齋藤です。
今回はテーブル設計の基本から、具体的な設計手法を記載します。

# 目次

1. [テーブル設計の基本](#1-テーブル設計の基本)
2. [エンティティと属性の定義](#2-エンティティと属性の定義)
   - [エンティティ](#エンティティ)
   - [属性](#属性)
3. [キーの設計](#3-キーの設計)
   - [主キー（Primary Key）](#主キープライマリキー)
   - [外部キー（Foreign Key）](#外部キーフォーリンキー)
   - [その他のキー](#その他のキー)
4. [正規化](#4-正規化)
   - [第1正規形（1NF）](#第1正規形1nf)
   - [第2正規形（2NF）](#第2正規形2nf)
   - [第3正規形（3NF）](#第3正規形3nf)
5. [テーブルのリレーションシップ](#5-テーブルのリレーションシップ)
6. [テーブル設計のベストプラクティス](#6-テーブル設計のベストプラクティス)
7. [まとめ](#7-まとめ)

## 1. テーブル設計の基本

テーブルは、データベース内でデータを格納するための基本単位です。各テーブルは、行（レコード）と列（フィールド）から構成されます。以下のステップでテーブル設計を進めます。

1. **エンティティの定義**: どのようなオブジェクトを表現するのかを明確に
2. **属性の定義**: 各エンティティが持つ情報（属性）を洗い出し
3. **キーの決定**: テーブル内でデータを一意に識別するためのキーを決定

## 2. エンティティと属性の定義

### エンティティ

エンティティとは、保存すべきデータの集合を表します。例えば、顧客や商品、注文などがエンティティになります。各エンティティは、ビジネスプロセスに関連する具体的な概念やオブジェクトを表現します。

### 属性

属性とは、エンティティが持つデータ項目のことです。例えば、顧客エンティティであれば「名前」「住所」「電話番号」が属性になります。属性を定義する際には、以下の点に注意します：

- **データ型の選定**: 整数、文字列、日付など、適切なデータ型を選ぶ
- **必須/任意**: 属性が必須か任意かを決定する
- **デフォルト値**: 属性にデフォルト値を設定する場合がある

## 3. キーの設計

### 主キー（Primary Key）

主キーは、テーブル内の各レコードを一意に識別するための属性または属性の組み合わせです。主キーの設計には以下のポイントがあります

- **ユニーク性**: 主キーは一意でなければなりません
- **非NULL**: 主キーはNULLを許可しません
- **不変性**: 主キーの値は基本的に変更されるべきではありません

### 外部キー（Foreign Key）

外部キーは、他のテーブルの主キーを参照するための属性です。外部キーはテーブル間のリレーションシップを定義します。外部キーの設定により、データの整合性を確保できます。

### その他のキー

- **代替キー（Alternate Key）**: 主キーとして選択されなかった候補キー
- **複合キー（Composite Key）**: 複数の属性を組み合わせて一意性を確保するキー

## 4. 正規化

正規化は、データの冗長性を排除し、データの一貫性を保つための手法です。主な正規形には以下があります

### 第1正規形（1NF）

- 各フィールドには単一の値のみを持つ（重複や繰り返しのグループを排除）
- テーブルは原子値のみを含む

### 第2正規形（2NF）

- 第1正規形を満たす
- 主キーに完全関数従属していない部分関数従属を排除

### 第3正規形（3NF）

- 第2正規形を満たす
- 主キーに非関数従属の推移的従属を排除

## 5. テーブルのリレーションシップ

リレーションシップは、テーブル間の関係性を定義します。代表的なリレーションシップには以下があります

- **1対1（One-to-One）**: 各レコードが他のテーブルの1つのレコードとだけ関係する
- **1対多（One-to-Many）**: 1つのレコードが他のテーブルの複数のレコードと関係する
- **多対多（Many-to-Many）**: 複数のレコードが他のテーブルの複数のレコードと関係する（中間テーブルを使用して実装）

## 6. テーブル設計の重要事項

- **冗長性の最小化**: データの重複を避け、一貫性を保つ
- **パフォーマンスの考慮**: インデックスを活用し、クエリパフォーマンスを向上させる
- **スケーラビリティ**: 将来的なデータ量の増加を見越して設計する
- **セキュリティ**: 機密データの暗号化やアクセス制御を設計に組み込む

## まとめ

テーブル設計は、データベースの効率性とスケーラビリティに大きな影響を与える重要なプロセスです。適切なエンティティと属性の定義、キーの設計、リレーションシップの設定により、データの整合性を確保し、効率的なデータ管理を実現することができます。正規化を通じて冗長性を最小限に抑えつつ、パフォーマンスやセキュリティにも配慮した設計をしましょう。

以上、齋藤でした。
SQLを書く際の覚書

こんにちは。齋藤です。
SQLはデータベース操作において強力なツールですが、効率的で読みやすいコードを書くためには、いくつかのポイントがあります。この記事では、SQLを書く際に注意すべきポイントや役立つヒントを紹介します。
## 目次
1. [クエリをシンプルに保つ](#クエリをシンプルに保つ)
2. [適切なインデックスを使用する](#適切なインデックスを使用する)
3. [結合の順序を考慮する](#結合の順序を考慮する)
4. [適切なデータ型を使用する](#適切なデータ型を使用する)
5. [NULL値の取り扱いに注意する](#NULL値の取り扱いに注意する)
6. [SQLインジェクション対策](#SQLインジェクション対策)
7. [まとめ](#まとめ)

## 1. クエリをシンプルに保つ

複雑なクエリはバグを生みやすく、パフォーマンスにも影響を与えます。以下の点に注意して、クエリをシンプルに保ちましょう。

- **一度に多くのことをしない**: クエリを小さく分割し、必要に応じてサブクエリやビューを使用します
- **読みやすい構造**: インデントや改行を使って、クエリを読みやすくします

### 例
```sql
SELECT customer_id, first_name, last_name
FROM customers
WHERE active = true
ORDER BY last_name;
```

## 2. 適切なインデックスを使用する

インデックスは検索を高速化しますが、書き込み操作が遅くなる可能性があります。使用する際は以下を考慮してください。

- **頻繁に検索に使用される列にインデックスを設定**
- **INSERTやUPDATEが多いテーブルでは、インデックスを減らすことを検討**

## 3. 結合の順序を考慮する

結合の順序はパフォーマンスに影響を与えるため、以下を考慮します。

- **小さなテーブルから大きなテーブルへ結合**
- **結合条件を適切に設定し、必要な列のみを選択**

### 例
```sql
SELECT o.order_id, c.first_name, c.last_name
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id;
```

## 4. 適切なデータ型を使用する

データ型はストレージとパフォーマンスに影響を与えます。適切なデータ型を選択しましょう。

- **数値は可能な限り小さなデータ型を使用**
- **文字列は適切な長さを指定する**
- **日付や時間はDATEやTIMESTAMPを使用**

## 5. NULL値の取り扱いに注意する

NULL値は予期しない結果を招くことがあります。以下の点に注意しましょう。

- **IS NULLやIS NOT NULLを使用してNULLを明示的に扱う**
- **COALESCEやNULLIFを使用してNULL値を処理する**

### 例
```sql
SELECT COALESCE(phone, '情報なし') AS phone_number
FROM customers;
```

## 6. SQLインジェクション対策

特にユーザー入力を含むクエリでは、SQLインジェクションに対する防御が重要です。

- **プリペアドステートメントやパラメータ化クエリを使用**
- **ユーザー入力をエスケープする**

## まとめ

SQLを書く際には、コードの読みやすさとパフォーマンスを常に意識することが重要です。シンプルで効率的なクエリを目指し、必要に応じてインデックスやデータ型を適切に選択しましょう。

以上、齋藤でした。
Homebrew: macOSの最強パッケージマネージャーをマスターしよう

# Homebrew: macOSの最強パッケージマネージャーをマスターしよう

## はじめに

macOSユーザーなら、一度は聞いたことがある「Homebrew」。でも、実際に使ってみると、その便利さに驚かされます。この記事では、Homebrewの基本から、ちょっとした裏技までを紹介します。これであなたもHomebrewの達人に！

## Homebrewとは？

Homebrewは、macOS用のパッケージマネージャーです。コマンドラインを使って、さまざまなソフトウェアを簡単にインストール、アップデート、アンインストールできます。

![スクリーンショット 2024-07-30 19.14.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75802/85bbc3f0-0175-e31b-d447-b8c38594acc9.png)

公式ページはこちら（日本語版）
https://brew.sh/ja/

## Homebrewのインストール

まずはHomebrew自体のインストールから始めましょう。ターミナルを開き、以下のコマンドを実行します：

```sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

インストールが完了したら、次のコマンドで確認しましょう：

```sh
brew --version
```

## Homebrewの基本的な使い方

### パッケージの検索

欲しいソフトウェアがあるかどうかを確認するには、以下のコマンドを使います：

```sh
brew search <パッケージ名>
```

例：

```sh
brew search wget
```

### パッケージのインストール

ソフトウェアをインストールするには、以下のコマンドを使います：

```sh
brew install <パッケージ名>
```

例：

```sh
brew install wget
```

### パッケージのアップデート

インストールしたソフトウェアを最新バージョンにアップデートするには、以下のコマンドを使います：

```sh
brew upgrade <パッケージ名>
```

すべてのソフトウェアを一括でアップデートすることも可能です：

```sh
brew upgrade
```

### パッケージのアンインストール

不要になったソフトウェアをアンインストールするには、以下のコマンドを使います：

```sh
brew uninstall <パッケージ名>
```

## Homebrewの便利な機能

### パッケージの情報表示

インストールする前に、パッケージの詳細情報を確認できます：

```sh
brew info <パッケージ名>
```

### インストール済みパッケージの確認

インストール済みのパッケージ一覧を表示するには、以下のコマンドを使います：

```sh
brew list
```

### タップの活用

Homebrewには「タップ」という追加リポジトリがあります。公式リポジトリにないパッケージをインストールするために使います。

```sh
brew tap <ユーザー名/リポジトリ名>
```

### Homebrew Services

Homebrewには、サービスを簡単に管理できる「brew services」があります。例えば、MySQLなどのデーモンを簡単に起動・停止できます。

```sh
brew services start mysql
brew services stop mysql
brew services restart mysql
```

### 自作スクリプトの管理

自分で作ったスクリプトもHomebrewで管理できます。GitHubにリポジトリを作成し、そこにスクリプトをアップロードして以下のコマンドでインストールします。

```sh
brew tap <ユーザー名/リポジトリ名>
brew install <スクリプト名>
```

## まとめ

Homebrewは、macOSユーザーにとって欠かせないツールです。この記事で紹介した基本的な使い方から応用までを活用して、快適な開発環境を手に入れましょう。まだHomebrewを使っていない方も、これを機にぜひ試してみてください！

Happy Brewing!:boy:
Macのキーリピートを速くしたい

## はじめに
Macのキー入力リピートをシステム設定より速くしたいと思ったので調べました。
戻すことも可能ですので試してみてください。
## 現在の設定を確認する
下記コマンドで現在の値が確認できます。
```
$ defaults read -g InitialKeyRepeat
$ defaults read -g KeyRepeat
```
## キーリピート速度を速くする
下記コマンドでキーリピートの速度を変更できます。数字で調整可能です。
```
$ defaults write -g InitialKeyRepeat -int 11
$ defaults write -g KeyRepeat -int 1
```
設定を適用するためには1度Macの再起動が必要です。

## 設定を戻す
下記コマンドで設定を戻すことが可能です。
```
$ defaults delete -g InitialKeyRepeat
$ defaults delete -g KeyRepeat
```

## まとめ
「control + B」や「control + H」の操作がとても快適になります。

## 参考記事
[[Mac] キーボードの反応速度を速くする方法 2](https://dev.classmethod.jp/articles/mac-keyboard-speed-2/)
TCPDFで、実線・点線・破線・二重線を引く方法

## はじめに

TCPDFで、罫線を表示する機会があったので、備忘録として残します。

## 環境

TCPDFのバージョンは`4.8.013`です。

## 表示例

上から実線・点線・破線・二重線です。

![スクリーンショット 2024-07-29 18.48.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1125523/6909c3a8-2cde-1ff2-0b62-1e5e6a2759dc.png)


## コード

`dash`の設定で、線の表示を変えています。
二重線は１行で表示する方法が無いため、実線を２回表示しています。

```php
	// 実線
	$solidLineStyle = ['dash' => '0'];
 	// Lineの引数（開始点のX座標、開始点のY座標、終了点のX座標、終了点のY座標、線種）
	$tcpdf->Line(10, 10, 100, 10, $solidLineStyle);

	// 点線
	$dottedLineStyle = ['dash' => '1, 4'];
	$tcpdf->Line(10, 20, 100, 20, $dottedLineStyle);

	// 破線
	$dashedLineStyle = ['dash' => '2'];
	$tcpdf->Line(10, 30, 100, 30, $dashedLineStyle);

	// 二重線
	$doubleLineStyle = ['dash' => '0'];
	$tcpdf->Line(10, 40, 100, 40, $doubleLineStyle);
	$tcpdf->Line(10, 41, 100, 41, $doubleLineStyle);
```

## 参考

http://tcpdf.penlabo.net/method/s/SetLineStyle.html

http://tcpdf.penlabo.net/method/l/Line.html

## 最後に

### GoQSystemでは一緒に働いてくれる仲間を募集中です！

ご興味がある方は以下リンクよりご確認ください。

https://goqsystem.recruit.site?qiita=491b468e3f257ac0651f
AtCoder　Bigginer　Contest　006 C スフィンクスのなぞなぞのO(1)解法について

問題文↓
https://atcoder.jp/contests/abc006/tasks/abc006_3
diff1158

以下,大人の足の数、老人の足の数、子供の足の数をa,b,c
とあらわすことにする。

解法:a+b+c=n,2a+3b+4c=mとして不定方程式を解く。

まず、2n>mもしくは4n<mのときは明らかに達成できない。
そうではない場合について考えると、

a+b+c=nなので両辺を2倍して2a+2b+2c=2nといえる。
これを先ほどの式から引くとb+2c=m-2nとなる。
よって、b=(m-2n)%2,c=(m-2n)/2と表せ、a=n-b-cなのでa=n-(m-2n)%2-(m-2n)/2と表せる。
以下　c++コード↓
```c++:しーぷらぷら1
#include<bits/stdc++.h>
using namespace std;

int main(){
  int n,m;cin >> n >> m;
  if(2*n>m or 4*n<m)cout << "-1 -1 -1\n";
  else cout << n-(m-2*n)%2-(m-2*n)/2 << " " << (m-2*n)%2 << " " << (m-2*n)/2 << '\n';
}
```

もっとシンプルにできないか考えてみる。
まずb (m-2n)%2となっているが、
2nは絶対に偶数なので、
(m-2n)%2=m%2 と表せる。
次にc　これはやらなくてもいいが、一応括弧を外しておく
(m-2n)/2となっているが、
・mが奇数の時　m=2k+1とあらわすと(2k+1-2n)/2=k-n
・mが偶数の時　m=2kとあらわすと(2k-2n)/2=k-n
よってm/2-nと表せるとわかる。
最後にa これはn-m%2-(m/2-n)でもいいが,
4n-m=2a+bがいえるので、a=(4n-m)/2。
・mが奇数の時 m=2k+1と表すと(4n-m)/2=2n-k-1
・mが偶数の時　m=2kと表すと(4n-m)/2=2n-k
よって2n-(m+1)/2と表せるとわかる。
以下　c++コード↓
```c++:しーぷらぷら2
#include<bits/stdc++.h>
using namespace std;
int main(){
  int n,m;cin >> n >> m;
  if(2*n>m or 4*n<m)cout << "-1 -1 -1\n";
  else cout << 2*n-(m+1)/2 << " " << m%2 << " " << m/2-n << '\n';
}
```
ちなみにこれをさらにbyte数を短くした以下のコードでこの問題のC++AC最短コードを達成できた。(2024/07/30時点)
```c++:しーぷらぷらショート?
#include<iostream>
using namespace std;int main(){int n,m;cin>>n>> m;if(2*n>m or 4*n<m)cout << "-1 -1 -1\n";else cout<<2*n-(m+1)/2<<" "<<m%2<<" "<<m/2-n<<'\n';}
```
hello world

this is just for testing post  nflsfd sfj skfjl ksjf flks jfklsj ffks ffkl fksl jfksd dffks ffkl sdfkf sdjkf sjkf sdkf ksd sfks fjkls jffkls jfkls djfks jflsflks fs
ksfjklsjf klsj flksjfksdj flsf 
lfjlksdjflksddjfksdjdflksdjf
 slkjflksjfklsjflks jfdslkf 
 lkskjdflksfl sl
 lks l
【JUnit】doReturn, thenReturnでの違い

junitで単体テストを書いているときに、`when + thenReturn`と`doReturn + when`の違いがよくわからなかったのですが、spyを使う場合に少し違いがあったので記録します

### junit version
```pom.xml
<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.12</version>
	<scope>test</scope>
</dependency>
```
以下のようなサンプルクラスでテストしてみます
```java
public class Sample {
	@Getter
	private boolean active = false;

	public boolean init(boolean active) {
		this.active = active;
		return active;
	}
}
```

## mockの場合
```java
@Test
public void test() {
    // thenReturn
	Sample sample1 = Mockito.mock(Sample.class);
	Mockito.when(sample1.init(true)).thenReturn(false);
	assertFalse(sample1.init(true));
	assertTrue(sample1.isActive());

    // doReturn
	Sample sample2 = Mockito.mock(Sample.class);
	Mockito.doReturn(false).when(sample2).init(true);
	assertFalse(sample2.init(true));
	assertFalse(sample2.isActive());
}
```
-> 差分なし.メソッド内部の処理は実行されず指定した返却値のみ返される

## spyの場合
```java
@Test
public void test() {
    // thenReturn
	Sample sample1 = Mockito.spy(new Sample());
	Mockito.when(sample1.init(true)).thenReturn(false);
	assertFalse(sample1.init(true));
	assertTrue(sample1.isActive());

    // doReturn
	Sample sample2 = Mockito.spy(new Sample());
	Mockito.doReturn(false).when(sample2).init(true);
	assertFalse(sample2.init(true));
	assertFalse(sample2.isActive());
}
```
-> thenReturnの場合**メソッド内部の処理は実行され**、指定した返却値が返される

ちなみに、他にもthenReturnだとvoidメソッドはスタブ化できないなどあるみたいです
[Unity] Sliderの設定と画像を変形せずに拡大させる方法 [UI, Sprite, Slice, 2D]

UnityのSlider使う度に勘で設定してるから、いい加減覚える為にも記事書いてみた。
<!--
:::note warn
書いてる途中に気づいたけど、Slider全般の設定というより、拡大しても変形したいSliderの設定について書いてるわ、思い出したら他の設定についても追記するわ。
::: 
-->
:::note info
**画像の設定**から画像を変形させずに拡大させる方法を書いてます
:::

# Sliderの作成
Hierarchyで右クリック、もしくはHierarchyの＋ボタンをクリックして
UI > Slider を選択　これだけでSliderとCanvasが作成できます

<img width="350" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849101/c96296d6-8bd7-4444-46a4-e3073d11ae78.png>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849101/f8a998d5-dae0-29a0-d7eb-0f427176b7be.png)

Canvasの設定についても記事を書く予定
<font color=gray size=10>PlayとPauseは関係ないです、、、</size></color>

## Sliderの説明
![スクリーンショット 2024-07-29 214724.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849101/df5d4530-ec19-7c48-416b-a8fadc9a8533.png)
↑見本
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849101/24705981-0346-bd26-17d0-f09b5b6d4b1a.png)
`Canvas`はキャンバスです、基本これないとUI表示できません
`Slider` Sliderというコンポーネントがアタッチされています
<details><summary>Sliderコンポーネントの軽い説明</summary>

<img width="400" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849101/a6ef444f-bb28-6949-b374-2a4f5e97ef9f.png>

全部説明するのは面倒なので、`On Value Chenged` についてだけ軽く説明します

### On Value Chenge
`On Value Chenge` はValueが変動した時に何をするかを設定できます。
下の例では値が変更した時`Audio Source`の`time`に`Value`を代入しています

:::note info
Dynamic floatの設定を使えば、コードを書かなくても`Value`を代入できます
:::
<img width="400" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849101/e1f85494-7bbd-68db-1e51-ba5c4d43a690.png>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849101/c3d1b758-ea97-f084-1d9a-0e36e60fdb5a.png)

</details>

`FillArea` は上の画像でいうと<font color=#FF1A8C>ピンク色の部分</font>です、`Value`の数値に応じて長さが変動します
`Background` は上の画像でいうと白い縁の部分です
    `Handle Slider Area` は上の画像でいうと`FillArea`の先にある<font color=FF1A8C>ピンクい円</font>です、**これを消してもユーザは`Value`を変更できます**

# 画像の設定
ぶっちゃけここからが本題です。
`Image`を正しく設定しないとSliderが変形するのです、そうならないようにまず
Sliderで使う画像の設定をすべて以下のようにします。
### Texture Typeの変更
![スクリーンショット 2024-07-29 214503.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849101/34c9efa0-c4d8-34c3-cf0f-24a8d5f4c061.png)
`Texture Type` を `Sprite` にする、これをすることで、`SpriteRenderer`と`Image`で使えるようになります。<font color=gray>以下のようにって言ったけど`TextureType`変えるだけでいいかも</font>
### Sprite Editorで編集
次に`Sprite Editor`を開き
<font color=00ff00>緑色の線</font>を適当に変更します
![スクリーンショット 2024-07-29 214548.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849101/1b58c60c-4c0c-435e-5b93-23fdbba83498.png)
この線は画像を拡大した時にどこを拡大するかを示しています
つまり画像の場合、縦に拡大し時はカーブの先端が縦に拡大され、横に拡大した時は先端のカーブが終わったところから拡大される
### Imageの設定
`Image`の`Image Type`を`Sliced`にします、これで変形せずに拡大ができるようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849101/32cfba48-7ac8-b04d-860d-829a3691dd01.png)

### 完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849101/a36fb0ff-4081-f347-6688-199c471e8dc9.png)



# 良かったらフォローして、他にもSNSやってるからそっちも見に行って
まだコンテンツ多くないと思うけど、、、
Javaの強みを徹底解説①：Javaのいいところ 

こんにちは NSS の江口と申します。
NSSでは入社の際に新人研修として`C言語`と`Java`を学習します。
その後現場に出てからも ずっと`Java`を利用してまいりました。
そのまま 15 年、特に疑問を抱くことなく過ごしてきたのですが、様々な言語が登場しては下火になっている中、根強い人気を誇っています。
私自身Javaは結構好きでこれからも発展してほしいので、改めてなぜこれほどまでに Java が強いのかを考察してまいりたいと思います。

# 理由① シェア

IPAが発表している資料によると、開発プロダクトの **42.4%** が Java で動作しているそうです。
[ソフトウェア開発 分析データ集 2022](https://www.ipa.go.jp/digital/chousa/metrics/hjuojm000000c6it-att/000102171.pdf)
これは対象プロダクトが**金融**関連が多いこともその一因だと思います。私は**金融**関連のプロダクトに携わることが多いのですが、
Javaを実行環境に選択しているプロダクトは本当に多いです。
既にシェアが高いし、大きな不満もない。なので次もJavaになる。ということなのかなと思います。
私個人としてはクライアント側に少し弱みがあると思いますが、サーバ側ではこれといった不満がないです。
実際クライアント側は `AWT`/`Swing`/`JavaFX` といずれも下火になっているので、Javaはサーバ側の実行環境として発展していくのだろうなと思います。

# 理由② Write once, run anywhere

今のご時世これをサポートする言語も多いので、ありがたみが半減しているかと思うのですが、十数年前の常識ですと、`C`や`C++`では実行環境に応じたソースの書き換えが必要でした。
例えば以下は、`Linux`にてソケットクライアントでメッセージを送信するプログラムとなります。

```cpp
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>

int main() {

    // ソケット生成
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);

    // 送信先アドレス・ポート番号設定
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(1234);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    // サーバ接続
    connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));

    // データ送信
    char send_str[] = "Hello.";
    send(sockfd, send_str, strlen(send_str), 0);

    // シャットダウン
    shutdown(sockfd, SHUT_RDWR);

    // ソケットクローズ
    close(sockfd);

    return 0;
}
```

ではこれと同等のものをWindowsで実装しようと思うと、

* 呼び出すライブラリは`sys/socket.h`ではなく`winsock2.h`を`include`する
* `close`ではなく`closesocket`を呼び出す

などといった違いがありますが、Javaであればこの差分は`JavaVM`が吸収してくれるので、コーディング自体は同一でよくなります。
レジストリや名前付きパイプなどは、どうしてもOS毎の機能的な差分を吸収しきれないことが多いですが、サーバであればほぼ網羅できるのではないかと思います。

# 理由③ オブジェクト指向

この考え方の導入により、機能を抽象化することができるようになり、協業がしやすくなったという側面があると思います。
これは後述するガベージコレクションの登場により、オブジェクトのライフサイクルの管理をする必要がなくなったということがよりオブジェクト指向を後押ししたと考えています。
登場人物としてのオブジェクトが登場し、それらがコラボレーションしながらシステムを構成していくわけなので、システムの説明もしやすくなりました。

# 理由④ ガベージコレクション

参照されていないメモリを勝手に解放してくれる仕組みです。先に述べたように設計でもプログラムでも面倒な非機能要件から解放されるのは大きいです。

![掃除アイコン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799996/8d7e7299-2ade-c395-bb4d-e91a82f9e6a2.png)

通常の株式取引のシステムであれば、

* トレーダー
* 銘柄
* 発注
* 約定

などに該当するオブジェクトを作成し、それらを組み合わせて設計します。
ガベージコレクションがない場合、

> トレーダーが発注するんだけど、この発注っていうものの生存期間はhogefugaで。。。

と考える必要があり、設計で盛り上がっているのになかなか水を差す制約ですよね。
何度か`C言語`でプロダクトを作成するプロジェクトに従事しましたが、メモリ管理には本当に気を付けて設計しますし、ヒートランなども念入りに実行することが多いです。
また、メモリリークについては自分たちが作成するソースコードはもちろんなのですが、利用しているライブラリ内でメモリリークしているというケースもあり、そういった場合はどうしようもなくなります。
`C言語`ではサードパーティ製のライブラリを導入する際には事前にヒートランなどを実行したり、すごく神経質になっていたのですが、
`Java`になってからは本当に不要なら`JavaVM`が勝手に片づけてくれるので、以前ほどライブラリの選定に神経質にならずに済むようになりました。近年はダウンロード数、スターの数、更新の頻度が相当低くない限り、躊躇することってあんまりないですよね。

# 理由⑤ コンパイル言語

これは当たり前だとも思えるのですが、いわゆるコンパイル言語なので、コンパイルしないと実行可能になりません。
実行前に文法的な不備は検出できるというのが良いです。いわゆるスクリプト言語と比較するとずっと動作する必要のあるサーバプログラムを想定した際に`Java`はやはり安心感があります。
`AWS Lambda`などは`Java`の場合はクラスロードの時間などもあり、`python`の方が適していると思いますが、常駐するアプリは`Java`がかなり強いと思います。

# まとめ

Javaの良いところをここまで述べてきました。今後もJavaが発展していってくれることを願います。次は`Java`の`JITコンパイラ`について投稿したいと思います。
Slackのアイコンを一覧化して印刷できるサイトを作ってみた

# 作ったもの
https://slack-icon-printer.onrender.com/
※renderでホスティングしているので定期的にお眠りになります。初回アクセスが15分以上かかる場合があるのでご了承ください。

# なにができるの？
Slackのアイコンを一覧化して印刷できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192137/2602531c-1f38-916e-cdb3-bcfa43e1cfd1.png)

# どういうときに使うの？
社員向けの名札を作るときに便利です。全社員が集まる会議などで名札を事前に作りたいときご活用ください。このままPDFで保存してキンコーズなどで厚紙印刷やシール印刷したらかっこいいと思います。

# 使い方
## Slackアプリ作成
以下にアクセスします。

https://api.slack.com/apps

「Create New App」ボタンを押します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192137/5283b488-04c2-2d35-f468-630e8c80e161.png)

「From Scratch」を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192137/433a0526-782b-6926-3bb7-3fb2b504df28.png)

適当な名前とインストールするWSを選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192137/0456b4e6-4b77-9248-4a22-9c788c15b60a.png)

「OAuth & Permissions」を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192137/395ab2ef-088b-ff5d-92d1-0d853dba6440.png)

中段にあるScopes > Bot Token Scopesから「Add an OAuth Scope」を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192137/9d11e83e-5208-db02-040b-1919356a040a.png)

「Users:read」を選択します。

:::note info
※`bots.info` `users.getPresence` `users.info` `users.list` のAPIが使えるようになります。このアプリではusers.listのみ使っています。
:::
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192137/09389ab7-0837-76c9-e1db-8f5ed960c828.png)

上に戻ると「install to Workspace」のボタンが有効化されます。このボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192137/b3a9f8fc-e53d-59d6-6def-a025290bbb6c.png)

「許可する」を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192137/7f6e1944-1a7c-5cbc-29be-2c4ade99ddaf.png)

戻るとtokenが表示されているのでコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192137/c03a81b5-95f3-1ee3-4f6e-35cd2063cb38.png)

## アプリにアクセス
以下のURLにアクセスします。

https://slack-icon-printer.onrender.com/

SlackのTokenを入力して「送信」ボタンを押します。

# ソースコード
Githubで公開済みです。(ReadMe書きます。すいません）

https://github.com/hyoshitake/slack_icon_printer
ウェブデザイン技能検定3級　合格体験記

# はじめに
皆さんこんにちは。はつかぜ株式会社　サポート室のSです。
本日はウェブデザイン技能検定3級に合格した時のことを書かせて頂きます。

# ウェブデザイン技能検定とは？
指定国家機関である特定非営利活動法人インターネットスキル認定普及協会が実施する国家試験で、技能試験と筆記試験に分かれています。1~3級まで等級が分かれており、各等級で技能と筆記の両方に合格することでウェブデザイン技能士を名乗ることができるようになります。

# 3級合格に使用した参考書
私が合格までに使用した参考書は以下の3冊です。参考書があまり種類豊富でないので、これらの本を何度も勉強するのが無難だと思います。
①改訂版 ウェブデザイン技能検定 3級 過去問題集 （FOM出版）
②ウェブデザイン技能検定 3級ガイドブック（ウイネット）
③ウェブデザイン技能検定 3級対策問題集（ウイネット）

①改訂版 ウェブデザイン技能検定 3級 過去問題集 （FOM出版）
技能試験、実技試験両方の過去問が過去7回分ほど収録されています。技能試験は毎回過去問と同様の問題が出題されるようですので、技能試験の対策はほぼこれだけで大丈夫です。

②ウェブデザイン技能検定 3級ガイドブック（ウイネット）
出題範囲の解説と、サンプル問題が載っています。出題範囲がコンパクトにまとめられているので便利です。

③ウェブデザイン技能検定 3級対策問題集（ウイネット）
出題範囲を網羅した問題集。全問暗記するくらいに何回も解くと、受験時の不安が少なくなると思います。
②と③を何回も解きつつ、不足していると感じるところは別途ネットなどで調べて覚えることがおすすめです。

# 学習時間
試験日まであまり時間がなかったので合計30時間くらいでしょうか。実技試験に関しては不安はありませんでしたが、筆記試験があまり暗記できておらず不安でした。自信満々で臨みたい場合はもう少し時間をかけて学習してもよいかもしれません。

# まとめ
ウェブデザインを仕事にしようと思う場合、3級だけでは知識的・技術的両方に足りないと思います。試験に合格しないと仕事ができないわけではないですが、自己研鑽の意味でも、2級以上の試験にも挑戦していけたら良いのではないかと思います。

はつかぜ株式会社では、IT学習や業務に役立つ情報を定期的にお届けしていきたいと思っています。
システム開発のお問い合わせ・ご相談はこちら
https://www.hatsukaze.co.jp/inquire/
【AppStoreConnect】プレビュー動画アップロード時のエラー対応メモ

## 概要
基本的にプレビュー動画の要件に則っていれば問題ない。
https://developer.apple.com/jp/help/app-store-connect/reference/app-preview-specifications

対応時にエラーとなった事象と、対応内容をメモとして残します。


## エラー1
:::note alert
Appプレビューのオーディオがサポートされていないか、破損しています。
:::

### 原因
オーディオ情報が仕様通りではなかった。

### 対応
- ボイスメモで適当な音を撮影
- iMovieで動画に設定
- 音量を0
- 書き出してアップロード

![スクリーンショット 2024-07-30 14.13.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469133/8ecba74a-e464-5394-196d-63384468ba22.png)

## エラー2
（細かいエラーメッセージ忘れました😅）

:::note alert
フレームレートが仕様通りではありません。
:::

### 原因
仕様ではフレームレートは毎秒 30 フレームまでだが、60フレームの動画をあげていた。

### 対応
ffmpegを用いてフレームレートを変更する。

参考：https://rils-k.hatenablog.com/entry/2021/02/03/192030

```sh
ffmpeg -i プレビュー.mp4 -filter:v scale=886:1920 -r 30 プレビュー_修正後.mp4
```

## Tips
### 解像度の変更
Adobeのサービスで簡単に動画の解像度を変更できる。

https://new.express.adobe.com/tools/resize-video?referrer=https%3A%2F%2Fwww.google.com%2F&url=%2Fjp%2Fexpress%2Ffeature%2Fvideo%2Fresize&placement=columns-1&locale=ja-JP&contentRegion=jp&%24web_only=true&_branch_match_id=1005793929630828840&_branch_referrer=H4sIAAAAAAAAAxWLQQvCMBSDf81224aKB4UiXkQ9TUHw2nXZ7Nb1PdrOib%2FeJ4TkIyGvlDjuq0q31CCyDiNTTMWCptTMpbN%2BrFA9d4%2F6ZprL9twcAjqEgKBe%2F2u2OWbrk2hZlrIn6h1KQ5MU%2BRyckhxYDB8OiFGog05zgNDbtiBJGewXOTttMMEnZcjNk4%2FFKndktIMadHGtc0M%2ByXxHb8mrgX8%2FeXfVuwAAAA%3D%3D

## 参考
https://zenn.dev/littleossa/articles/add50f1f7abd37
【JavaScript Primer学習メモ】const、let、varそれぞれの方法で宣言した変数の違い

## はじめに
JavaScript Primerの[変数と宣言](https://jsprimer.net/basic/variables/)の内容を復習しやすいように、まとめました！
js初学者で、変数を宣言する場合はconstを使用するのが良いのかな...?くらいのあいまいな理解だったので、const、let、varの違いについてしっかり学べてスッキリしました！

## const
- 再代入できない変数の宣言とその変数が参照する値（初期値）を定義できる
     ```
     const 変数名 = 初期値;
     ```
- 再代入をすると、エラー（TypeError）が発生する。 エラーが発生するとそれ以降の処理は実行されなくなる
     ```
     const bookTitle = "JavaScript Primer";
     bookTitle = "新しいタイトル"; // => TypeError: invalid assignment to const 'bookTitle'
     ```

## let
- 値の再代入が可能な変数を宣言できる
- 何度でも値の代入が可能
     ```
     let count = 0;
     count = 1;
     count = 2;
     count = 3;
     ```
- letはconstとは異なり、初期値を指定しない変数も定義できる
  - 初期値が指定されなかった変数はデフォルト値としてundefinedという値で初期化される（undefinedは値が未定義ということを表す値）
     ```
     let bookTitle;
     // `bookTitle`は自動的に`undefined`という値になる
     ```

## var 
- varの使い方はletとほとんど同じ。「letはvarを改善したバージョン」
  - 値の再代入が可能な変数を宣言できる
     ```
     var bookTitle = "JavaScript Primer";
     ```
  - 初期値がない変数を宣言でき、変数に対して値の再代入もできる
     ```
     var bookTitle;
     bookTitle = "JavaScript Primer";
     bookTitle = "新しいタイトル";
     ```
- varを利用することは避けたほうがよい
  - varには同じ名前の変数を再定義できてしまう等のさまざまな問題がある
  - ほとんどすべてのケースでvarはconstかletに置き換えが可能


## まとめ
再代入を禁止することで、ミスから発生するバグを減らすことが期待できる。 
そのため変数を宣言する場合には、まずconstで定義できないかを検討し、できない場合はletを使うことを推奨している。
C/C++ 配列を特定の値で初期化する方法3選

# for 文
最もオーソドックスな方法でしょう。
`H * W` の二次元配列を、標準入力から得た値 `x` で埋めます。

## コード例
```c:C
#include <stdio.h>

#define H 100
#define W 100

int main() {
  int x;
  scanf("%d", &x);

  int A[H][W];
  for (int i=0; i < H; ++i)
    for (int j=0; j < W; ++j)
      A[i][j] = x;

  return 0;
}
```

# memset
`H * W` の二次元配列を `-1` で埋めます。

## コード例
```c:C
#include <stdio.h>
#include <string.h>

#define H 100
#define W 100

int main() {
  int A[H][W];
  memset(A, -1, sizeof(A));

  return 0;
}
```

## 解説
引数の意味は以下の通りです。

1. 配列の先頭を指すポインタ
1. 値（**1byte**）
1. 配列の大きさ（**byte数**）

`char txt[100];` `memset(txt, 'A', sizeof(txt));` のように、文字列に対して使う例だと結果をイメージしやすいでしょうか。

### memset の欠点
`1` や `2` など、ほとんどの数は `memset` で埋めるのに適していません。
`memset(A, 1, sizeof(A))` というコード自体には問題ありませんが、配列 `A` の中身は `1` ではなく `16843009` になってしまいます[^1]。

その理由は、引数の解説で byte を強調したところからお察しかもですが、各値が 1byte 単位で埋められていくからです。
`int` は 32bit == 4byte なので、1byte 単位で `1` (== `0x01`) を埋めていくと `int` の値としては `16843009` (== `0x01010101`) になる、という動作だったのでした。

### memset が有効な場合
代表例は `0` と `-1` の 2 つです[^2]。
`0` で初期化するのであれば `int A[H][W] = {};`[^3] のように、宣言と同時に初期化する方法も簡単です。
珍しい例では、`memset(A, 0x3f, sizeof(A))` として「大きな値」で埋める使い方を競技プログラミングで見かけました。
`0x3f` が選ばれた理由は、「 2 倍しても型の最大値を超えない、できるだけ大きい数」という競技プログラミング側の要求を満たすからでしょう。

# fill_n （C++限定）
`H * W` の二次元配列を、標準入力から得た値 `x` で埋めます。

## コード例
```c++:C++
#include <iostream>
#include <algorithm>
using namespace std;

constexpr int H=100, W=100;

int main() {
  int x;
  cin >> x;

  int A[H][W];
  fill_n(&A[0][0], H*W, x);
}
```

## 解説
引数の意味は以下の通りです。

1. 配列の先頭を指すポインタ
1. 配列の大きさ（要素の個数）
1. 値

`memset` の第二引数と第三引数の役割が逆になったようなインターフェースですね。

`memset` のコード例からも分かる通り、単に `A` と書いても配列の先頭を指すポインタが得られます。
しかし、 `fill_n` は賢く、ポインタ `A` が持つ配列の大きさの情報を関数内部でも保持しているため、「`*A` の型と `x` の型が違う」と怒られてしまいます。
そのため、 `&A[0][0]` のようにして `int *` 型のポインタを渡しています。
`&A[0][0]` の他、`(int *)A` のようにキャストしてもよいでしょう。

`memset` ではできなかった `1` や `2` での埋めも `fill_n` ならできます。すばらしいですね。
そもそも C++ なら `vector` クラスを使えばよいという話はありますが、「動的メモリ確保は避けたい！」といったニーズで、あえて C の配列を使う場合には `fill_n` の使いどころかもしれません。

---
以上、配列を特定の値で初期化する方法3選でした。何かの役に立ったら幸いです。


[^1]: 環境依存ですが、多くの環境でこうなるでしょう。
[^2]: 環境依存ですが、ほとんどの環境（符号付き整数が2の補数表現である）で「有効な場合」に当てはまるでしょう。
[^3]: C では、 `= {}` は NG らしいのですが、問題なく動く環境が多いです（たぶん）。`= {0}` とすれば OK です。
オンプレミス環境からAutomationCloudへの移行チェックポイント

## 初めに
オンプレミス環境からAutomationCloud（以下、クラウド環境）へ移行する際のチェックポイントを記載します。
## 事前準備
### オンプレミス環境のモダンフォルダ化
クラシックフォルダーのままでは各エンティティをクラウド環境へ移行できないため、オンプレミス環境のモダンフォルダ化を推奨しています。

### Stduio/StudioX/Robot（Assistant）のバージョン確認
クラウド環境Orchestratorへ接続するためには、Stduio/StudioX/Robotのバージョンを直近3世代にする必要があります。直近3世代以前のバージョンではクラウド環境Orchestratorへ接続できません。
### クラウド環境へ接続するための通信設定
クラウド環境を利用するためには、ファイアウォール等の設定が必要になる場合があります。公式ドキュメントに従い必要な設定を行ってください。
[AutomationCloud：ファイアウォールを構成する](https://docs.uipath.com/ja/automation-cloud/automation-cloud/latest/admin-guide/configuring-firewall)
[Studio/StudioX：Studio が接続するサービス](https://docs.uipath.com/ja/studio/standalone/2023.10/user-guide/services-studio-connects-to)
[Robot（Assistant）：ロボットが接続するサービス](https://docs.uipath.com/ja/robot/standalone/2023.10/user-guide/services-the-robot-connects-to)
## 移行作業
移行作業については、①移行ツールの利用＊、②OrchestratorManagerの利用＊、③新規設定（ツール利用せず、AutomationCloudを構築）の方法があります。
[Automation Cloud 移行ツールを使用する](https://docs.uipath.com/ja/automation-cloud/automation-cloud/latest/admin-guide/using-the-migration-tool)
[Orchestrator Manager](https://marketplace.uipath.com/listings/orchestrator-manager/versions)

＊注意：すべてのエンティティ（項目）を移行できるわけではありません。（ユーザー・ロボット、ロールなど）

#### エンティティ毎のOrchestratorManagerでの移行可否一覧
|エンティティ|移行作業概要　|
|-----------|------------|
| マシン      | 移行対象外※マシンテンプレートへ変更       |
| ロール       | 移行不可​        |
| ユーザー/グループ​      | 移行不可​        |
| ロボット       | 移行対象外        |
| パッケージ/ライブラリ       | 移行可        |
| フォルダ       | 移行可        |
| マシンテンプレート​       | 移行可        |
| プロセス       | 移行可        |
| アセット       | 移行可        |
| キュー       | 移行可        |
| トリガー       | 移行可        |

## その他
移行スケジュール目安を紹介します。
規模にもよりますが、準備期間から運用開始まで凡そ半年程度かかります。
ただし、モダンフォルダ化やStudio/StudioX/Robotのバージョンアップを実施する場合はさらにかかかります
＊モダンフォルダ化：3ヶ月程度・Studio/StudioX/Robotバージョンアップ：2-3ヶ月程度
型番調べの備忘録

型番調べの備忘録

ストレージの種類と型番を調べようと思ったのだが、`wmic diskdrive`でも`C://`のプロパティ>ハードウェアでも、`Newtech NRCP-KT622A-F1`が返ってきてしまって、これを調べてもなんだかよく分からなかった。
(「SATA-RAID」や「ミラーカード」なんかの単語は出てきたけれども)

ここでもC君に相談していろいろやっていると、結果的には、PowerShellコマンドの`Get-PhysicalDisk`が解決してくれた。
(SSDだった)

Newtechはストレージ系の日本メーカーらしい。

キーワードから出てきたネットのカタログを見てみると、
>...に対応した内蔵型ミラーリングRAIDコ
ントローラボードです。ハードディスクの1台が故障した場合でも、もう1台の
ハードディスクによりコンピュータの稼動を止めることなく継続運用が可能で
す。故障したハードディスクが交換されれば自動的にデータをコピーし、ミラ
ーリングの状態に復帰します...
>https://messe.nikkei.co.jp/files/SS4610/6-201612221428160701.pdf

と記載があるので、ミラーカードとはRAID1の機能を持つ機器セットのことか？

つまりは、参照コマンドを打っても、SSDを直に見ている訳ではなかったので、うまい結果が出てこなかった...ということかもしれない。
~~　ハード知識分からねえ...(愚痴)　~~
＃14　github のイベントを backlog に通知する

## 概要
リポジトリ管理は github、課題管理は backlog で行っているプロジェクトがあり、backlog 上にプルリクエストの情報を都度記載するのが大変だったため、プルリクエストが作成/クローズされたタイミングで、自動的にbacklogにコメントが登録されるようにしました。

## 仕組み
github actions を用いて gitイベントをトリガーし、backlog API でコメント登録をします。
backlog APIの実行には、[Backlog Notify](https://github.com/marketplace/actions/backlog-notify)を使用しました。
実行の条件として、プルリクエストのタイトルにBacklogの課題番号の記載が必要です。

## 実装

{プロジェクトルート}/.github/workflows に以下のファイルを配置します。
project_key, api_host, api_key の欄にはbacklogから取得した設定を入力します。
今回は、コミットプッシュ時はトリガー対象外とし、プルリクエストの作成/クローズのみを対象としています。


```yaml:backlog-notify.yml
name: Backlog Notify

on:
  pull_request:
    types:
      - opened
      - reopened
      - ready_for_review
      - closed

jobs:
  notify:
    runs-on: ubuntu-latest
    steps:
      - name: Backlog Notify
        uses: bicstone/backlog-notify@v4.0.2
        with:
          project_key: ******
          api_host: ******
          api_key: ******
```

## 確認
上記実装後、実際にプルリクを作成してみました。
すると

狙い通り、backlogに自動でコメントが登録されました！
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333834333038342f65326162346136362d393332652d333637642d656430322d66373063646165653065623.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843084/4bc1fc21-7bae-9f42-aca0-22dff4adcc9f.png)


プルリクをマージについても
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333834333038342f34313862343230622d393437652d313964612d313836372d3730663736613439323730.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843084/8a8e1c76-9509-6b02-ee32-224094ada353.png)


同様に、無事動作しています。
登録されるコメントの内容については、今回はデフォルトのままにしていますが、オプショナル設定で変更可能です。

## 最後に
今回はbacklogとgithubを連携してみました。手軽に導入できるので、運用の煩わしさで困っている方の参考になれば幸いです。
出典: https://github.com/marketplace/actions/backlog-notify
Box Captureを使ってみよう!!

**はじめに**

今回は、Box社のクラウドストレージサービス「Box」の機能である「Box Capture」のインストールから使い方までを、分かりやすく説明したいと思います！

<br>

**どんな時に使うの？？**
 ・外出先からモバイルアプリを使い、ファイルチェックする。
➡スマホでもファイルのレビューや承認が出来て便利。
・Boxノートに書かれた議事録をスマホからチェック。
➡いつでも、どこでも議事録が見られる
・展示会や工事現場で撮影した写真を、スマホからBoxへアップロード。
➡スマホ・タブレットだけで現場作業が完結して便利！

<br>

**Box CaptureとBox Driveはどう違うの？？**
| 特徴 | Box Drive | Box Capture |
|:-----------|:------------|:------------|
| 主な機能 | クラウドストレージのデスクトップアプリケーション | モバイルデバイスからコンテンツをキャプチャするアプリ |
| 目的 | ローカルファイルシステムとクラウドストレージの統合 | モバイルデバイスから直接Boxにアップロード |
| 対応デバイス | Windows, Mac | iOS |
| ファイル管理 | ローカルフォルダと同じようにクラウドファイルを管理 | 写真、ビデオ、ドキュメントのスキャンとアップロード |
| オフラインアクセス | 可能 | 不可 |
| ファイル同期 | 自動同期 | 自動同期なし、手動アップロード |
| 利用シーン | デスクトップでの作業効率向上 | フィールドワーク、モバイルでの迅速なドキュメント管理 |

<br>

**目次**
1.	Box Captureのインストール
2.	データの選定
3.	フォルダの作成
4.	データの移行
5.	使用してみた感想

<br>

**1. Box Captureのインストール**
まず、Box Captureを使うためには、インストールが必要です。手順を参考に、サクサクっとインストールしちゃいましょう！
必要なもの
・スマートフォン（iOSまたはAndroid）
・インターネット接続
・Boxアカウント

①	App StoreまたはGoogle Play Storeで「Box Capture」を検索し、ダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799749/3a955462-7219-bd9c-56e9-84fc5bf70950.png)

②	ダウンロードが完了したら、アプリを開きます。
③	Boxアカウントでログインします。
![Image (3).jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799749/9fa39fb3-63a6-b1d2-b0e3-68a60e15ce9f.jpeg)


<br>
 
**2.データの選定**
Box Captureで何を最初に撮影してアップロードするか迷ってしまいますよね？そこで、まずは共有したいデータを選んでみましょう！

ポイント!!
・重要なデータやよく使うデータからアップロードするのがおすすめです。
・大きなファイルの場合、インターネット環境によっては時間がかかる場合があるので、注意が必要です。

<br>

**3. フォルダの作成**
Box Captureで撮影したデータを整理しやすいようにフォルダを作成しましょう！

①	Box Captureアプリを開きます。
②	下部メニューから「Captureのアップロード」を選択します。
![Image (4).jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799749/e92ebd2b-c5ea-3e51-0760-4811c191f0f6.jpeg)

③	左下の「フォルダを作成」を選択します。
![Image (5).jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799749/183de27b-2409-add6-9c61-1e5e27a03199.jpeg)

④	フォルダ名を入力して「保存」をタップします。
![Image (6).jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799749/791e99b9-935c-4d11-67a5-455f65a6468f.jpeg)

⑤	右下の「このフォルダを使用」をタップします。これで準備はOKです！
![Image (8).jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799749/ba21c526-9c89-4591-4d84-e7948fe8abb4.jpeg)


<br>

**4. データの移行**
いよいよ、データをBox Captureで撮影してアップロードします！

①	Box Captureアプリを開きます。
②	カメラアイコンをタップして、撮影を開始します。
![88.jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799749/51535997-c103-82af-defa-d5c1068cff45.jpeg)

③	撮影が完了すると、自動的にBoxにアップロードされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799749/4181e2bb-9fcc-5155-860c-6ce7cd79214a.png)


<br>

**5. 使用してみた感想**
実際にBox Captureを使ってみて、便利だなと感じた点がいくつかあります！

・直感的な操作性 : スマートフォンから直接撮影してクラウドにアップロードできるので、非常に使いやすいです。撮影した写真や動画がすぐにBoxに保存されるため、手間がかかりません
・セキュリティ対策 : Box Captureはセキュリティ面でも優れており、データの暗号化やアクセス制限設定が充実しています。機密情報を扱う場合でも安全に利用できます。

<br>

**まとめ**
Box Captureは、シンプルな操作性と強力な機能を兼ね備えた非常に便利なツールです。ビジネスシーンはもちろん、日常の様々な場面でも活用できるので、ぜひ試してみてください！

<br>
<br>

補足
Boxには、他にもたくさんの便利な機能があります。詳細は、Boxのヘルプページやサポートドキュメントなどを参照してください。
＃12　【入門】Javadocまとめ

# Javadocとは
Javaのクラスやフィールド、メソッドに記述したコメントからドキュメントを生成するツールです。
Javadocに要素の説明や引数、戻り値に関する情報などコメントを記載することで、HTML形式のドキュメントを生成することができます。

## 利点
- 可読性の向上
- IDEでメソッドにカーソルを合わせたときJavadocが表示されるようになる
- コマンドを使い、各説明をHTMLファイルに出力したAPIドキュメントを作成できる

# 書き方
要素の宣言前、「/** ～ */」の間にコメントを記述します。

## 主なタグ
|タグ|用途|
|:--|:--|
|@&#xFFF0;author 名前|クラスやメソッドの作成者を記述する。|
|@&#xFFF0;deprecated 説明|非推奨（廃止）されたクラスやフィールド、メソッドであることを示す。非推奨になった理由などを記述する。|
|@&#xFFF0;param 引数名 説明|メソッドのパラメータについて説明を記述する。|
|@&#xFFF0;return 説明|メソッドの戻り値について説明を記述する。|
|@&#xFFF0;since バージョン|クラスやメソッドが作成されたバージョンを記述する。|
|@&#xFFF0;throws 例外クラス 説明|メソッドでスローされる例外についての説明を記述する。(@&#xFFF0;exceptionタグと同じ使い方)|
|@&#xFFF0;version バージョン|クラスやメソッドの現在のバージョンを記述する。|
|{@&#xFFF0;link}|Javadocタグの中で文字列を表示する場所の中に参照リンクを表示したい場合に使用する。<br>タグ内部は{@&#xFFF0;link package.class#member label}の形式で記述する。|

# 記述例
```java
/**
 * Calculatorクラスは、基本的な計算を行うためのクラスです。
 * 詳細な情報については、{@link sample.Calculator} を参照してください。
 *
 * @author Tarou
 * @version 1.0
 */
public class Calculator {
    /**
     * addメソッド
     * 2つの整数を加算して結果を返します。
     *
     * @param a 加算する整数
     * @param b 加算する整数
     * @return 加算結果
     */
    public static int add(int a, int b) {
        return a + b;
    }

    /**
     * mainメソッド
     * addメソッドを呼び出します。
     * 
     * @param args コマンドライン引数
     */
    public static void main(String[] args) {
        int result = add(5, 3);
        System.out.println("加算結果: " + result);
    }
}
```

# javadocコマンドを実行する
## コマンド例
親カレントリまで移動しjavadocコマンドを実行します。
```
javadoc -encoding UTF-8 -d ../docs -author -version Calculator.java
```
※ 「Calculator.java」からドキュメントを生成します。
※「-encoding UTF-8」で文字コードを指定します。
※ 「-d」オプションで「../docs」を出力先ディレクトリに指定しています。
※ 「-author」「-version」オプションで「@&#xFFF0;author」「@&#xFFF0;version」の情報をそれぞれドキュメントに追加しています。

## APIドキュメントを確認する
コマンド実行後、「-d ../docs」配下に生成された「index.html」ファイルをブラウザで開くとドキュメントを確認することができます。

# 最後に
今回はJavadocとよく使われるタグについて説明しました。
効率よく開発を行えるよう、読みやすいコメントをつけていきたいですね！

出典：[Java本格入門～モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで](https://gihyo.jp/book/2017/978-4-7741-8909-3)
#09　PHP でリダイレクトがうまくいかないときに確認すること

## はじめに
今回は備忘録としてheader 関数でよくあるエラーの原因をまとめました。
「PHP でリダイレクトしたいのにうまくいかない…。」
そんな方に確認していただきたい内容です。

## PHPでリダイレクトする方法
header 関数は、HTTP ヘッダを送信する役割があります。
Location を使うことで指定した URL へ遷移することができます。

~~~php
<?php
header("Location: http://www.example.com/");
exit;
?>
~~~

※ URL は絶対パスでも相対パスでも指定できます。
※ リダイレクト以降のコードが実行されないよう exit 関数で処理を終了させています。


## よくあるエラーとその原因

### 1. HTML の出力後に header() を呼び出している
~~~php:例1
<html>
</html>
// header() の前に出力している
<?php
header("Location: http://www.example.com/");
exit;
?>
~~~
header() はすべての出力の前に呼び出す必要があります。
echo 、print 、HTML 等の出力前に呼び出してください。

### 2. header() の前に不要なスペースや改行がある
~~~php:例2-1
<?php

header("Location: http://www.example.com/");
// header() の前で改行している
exit;
?>
~~~

~~~php:例2-2
 <?php
header("Location: http://www.example.com/");
// php タグの前にスペースがある
exit;
?>
~~~

php タグの中だけでなく、php タグの前にスペースや改行がある場合も
HTML を出力したとみなされエラーになります。

### 3. 記述を間違えている
~~~php:例3
<?php
header("Location : http://www.example.com/");
// 「"Location : 」では「:」の位置が正しくない
exit;
?>
~~~
正しくは「("Location: http～");」です。
「:」とスペースの位置が正しくないといけません。

## 最後に
リダイレクトさせるにも細かい決まりがありました。
見落としやすい部分もあるので、注意してコーディングしていきたいですね。
以上です。


出典： https://www.php.net/manual/ja/function.header.php
#02 AWS でスナップショットの作成とインスタンスの復元をする

# はじめに
今回はインスタンスの復元を行いました。

    バックアップを取りたいインスタンスのスナップショットを取得
    → そのスナップショットをもとにボリュームを作成
    → 作成したボリュームと新規インスタンスのルートボリュームを置き換える

という方法で復元していきます。

# 1. Amazon EBS スナップショットの作成
スナップショットとは、ある瞬間のファイルやディレクトリなどのイメージを保存したものです。
Amazon EBS スナップショットは、Amazon EBS ボリュームのデータを新しい EBS ボリュームに復元するために必要な情報を Amazon S3 にバックアップしてくれます。

## 手順
> 1. Amazon EC2 コンソール ( https://console.aws.amazon.com/ec2/ ) を開きます。
> 
> 2. ナビゲーションペインで、[Snapshots] (スナップショット)、[Create snapshot] (スナップショットの作成) の順に選択します。
> 
> 3. [リソースタイプ] で、[ボリューム] を選択します。
> 
> 4. [Volume ID] (ボリューム ID) で、スナップショットの作成元となるボリュームを選択します。
> 
> 5. [Encryption] (暗号化) フィールドは、選択したボリュームの暗号化ステータスを示します。選択したボリュームが暗号化されている場合、スナップショットは同じ KMS キーを使用して自動的に暗号化されます。選択したボリュームが暗号化されていない場合、スナップショットは暗号化されません。 
> 
> 6. [Create snapshot] (スナップショットを作成) を選択します。

出典：https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/working-with-snapshot-archiving.html

# 2. インスタンスの復元
復元用に空のインスタンスを立ち上げると紐づいたボリュームが自動的に作成されるので、そのボリュームをデタッチし、代わりに復元したいスナップショットを保持しているボリュームをアタッチします。
（新規ボリュームと復元したいボリュームを交換するイメージ）

## 手順
> 1. 取得したスナップショットは、EC2の管理画面のElastic Block Storeのスナップショットで確認できます。対象のスナップショットにチェックを入れ、「アクション」のプルダウンメニューから「スナップショットからボリュームを作成」で、スナップショットの内容でボリュームを作成できます。
> 
> 2. 新しいボリュームの ID を書き留めます。
> 
> 3. [Instances] (インスタンス) ページで、ボリュームを置き換えるインスタンスを選択し、インスタンス ID を書き留めます。
> 
> 4. インスタンスが選択された状態で、[Storage] (ストレージ) タブを選択します。[Block devices] (ブロックデバイス) セクションで、置き換えるボリュームを検索し、ボリュームのデバイス名を書き留めます (例: /dev/sda1)。
> 
> 5. ボリューム ID を選択します。
> 
> 6. [Volumes] (ボリューム) 画面で、ボリュームを選択し、[Actions] (アクション)、[Detach volume] (ボリュームのデタッチ)、[Detach] (デタッチ) の順に選択します。
> 
> 7. ステップ 1 で作成した新しいボリュームを選択し、[Actions] (アクション)、[Attach volume] (ボリュームのアタッチ) の順に選択します。
> 
> 8. [Instance] (インスタンス) および [Device name] (デバイス名) に、ステップ 2 で書き留めたインスタンス ID とデバイス名を入力し、[Attach volume] (ボリュームのアタッチ) を選択します。

出典：https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-attaching-volume.html

# 余談
ボリュームの置き換えはEC2インスタンスを実行しながら行うことができるので、インスタンスを停止せずに改修できるという利点があります。

## 実行中のEC2インスタンスのルートボリュームを置き換える
> 1. Amazon EC2 コンソール (https://console.aws.amazon.com/ec2/) を開きます。
> 
> 2. ナビゲーションペインで、[インスタンス] を選択します。
> 
> 3. ルートボリュームを置き換えるインスタンスを選択し、[Actions] (アクション)、[Monitor and troubleshoot] (監視とトラブルシューティング)、[Replace root volume] (ルートボリュームを置換) の順に選択します。
※ 選択したインスタンスが [running] 状態の場合、[Replace root volume] (ルートボリュームを置き換える) アクションは無効です。
> 
> 4. [Replace root volume] (ルートボリュームを置換) の画面で、次のいずれかの操作を行います。
> 
>     - 置換用のルートボリュームを初期起動状態に復元するには、スナップショットを選択せずに [Create replacement task] (置換タスクを作成) を選択します。
> 
>     - 置換用のルートボリュームを特定のスナップショットに復元するには、[Snapshot] (スナップショット) で、使用するスナップショットを選択し、[Create replacement task] (置換タスクを作成) を選択します。
> 
>     - AMI を使用して置換用ルートボリュームを復元するには、[AMI] で使用する AMI を選択し、[Create replacement task] (置換タスクを作成) を選択します。
> 
> 5. 置換タスクの完了後に元のルートボリュームを削除するには、[Delete replaced root volume] (置き換えられたルートボリュームを削除) を選択します。

出典：https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/replace-root.html

ちなみに、AMIでインスタンスを復元する場合は、インスタンス全体をイメージで保存して復元できるため、インスタンスを立て直す際の設定などの操作が省けます。

# 最後に
スナップショットやボリュームを保持しているとAmazon EBS の料金が発生します。
ゴミ箱の中にあるスナップショットも対象ですので消し忘れにご注意ください！
以上です。
linux でよく打つコマンドを知りたい時

## コマンド - bash

```bash
history | awk '{$1=""; print substr($0,2)}' | sort | uniq -c | sort -rn | head -n 10
```

alias したい物あったけどなんだっけ、という時に使う

## 解説 - 表示結果

左の数字は打ち込んだ回数。右は打ち込んだコマンド

```
  74 git st
  56 dku
  40 git df
  28 docker attach myapp
  27 git add .
  26 git push origin HEAD
  16 dkd
  13 git co develop
  11 login_myapp
```

最後の `head -n 10` を取れば全コマンドが見られる

```bash
history | awk '{$1=""; print substr($0,2)}' | sort | uniq -c | sort -rn
```

```
  74 git st
  56 dku
  40 git df
  28 docker attach myapp
  27 git add .
  26 git push origin HEAD
  16 dkd
  13 git co develop
  11 login_myapp
   7 git co .
   7 cd workspace/myapp
   6 ls
   6 git pull
   5 git log
   5 docker exec -it mydb /bin/bash
```
Neovimでファイル名とバッファ内容をコピー

生成AIにコードを入力する際、ファイル名とバッファの中身を手でコピーしていたのですが、一発でできるようにコマンドを作りました。

Copilot向けのプラグインを入れて、チャットで聞いてたりもしていましたが、やはりClaude 3 OpusやGPT-4oに聞いた方が良い結果が得られたりするのでいまだにコピペしてやってます:cry:
便利すぎて毎日使ってるので、Qiitaにメモしておきます・・・！

## ファイル名とバッファの内容をコピー

現在開いているファイルのパスとバッファ内容を、コードブロック付きでクリップボードにコピーします。
キーマップは好みで変えてください。


```lua:keymaps.lua
-- ファイル名とバッファ内容をコピー
local function copy_buffer_with_path_and_code_block()
  local path = vim.fn.expand "%:."
  local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
  local content = table.concat(lines, "\n")
  local text = string.format("%s\n```\n%s\n```\n", path, content)
  vim.fn.setreg("*", text)
  vim.notify("Copied buffer: " .. path, vim.log.levels.INFO)
end

vim.keymap.set("n", "<Leader>Y", copy_buffer_with_path_and_code_block, { noremap = true, silent = true })
```

任意のファイルを開き、`<Leader>Y`をすると下記がコピーされてるはずです

~~~lua:サンプル
init.lua
```
require "global_utils"
require "lua_rocks"
require "base"
require "autocmds"
require "options"
require "keymaps"
require "init_lazy"
```
~~~


## ファイルパスをコピー

パスをコピーする関数もおまけで貼っておきます


```lua:keymaps.lua
-- ファイルパスをコピー
local function copy_current_file_path()
  local path = vim.fn.expand "%:."
  vim.fn.setreg("*", path)
  vim.api.nvim_echo({ { "Copied: " .. path, "None" } }, true, {})
end
Keymap("<Leader>yp", copy_current_file_path)

vim.keymap.set("n", "<Leader>y", copy_current_file_path, { noremap = true, silent = true })
```
CMake configuration failedの１例

pip を使ってのライブラリのインストールの際に cmake を使ってソースのtarファイルからbuild が走ることがある。

そのようなライブラリのインストールの際に、次のようにbuildが失敗することがあった。

## 失敗例
```
pip3 install pyexr
Collecting pyexr
  Using cached pyexr-0.4.0-py3-none-any.whl.metadata (4.5 kB)
Collecting OpenEXR>=3.2.3 (from pyexr)
  Using cached openexr-3.2.4.tar.gz (1.7 MB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: numpy>=1.20.0 in /usr/local/lib/python3.8/dist-packages (from pyexr) (1.24.4)
Using cached pyexr-0.4.0-py3-none-any.whl (6.9 kB)
Building wheels for collected packages: OpenEXR
  Building wheel for OpenEXR (pyproject.toml) ... error
  error: subprocess-exited-with-error
  
  × Building wheel for OpenEXR (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [89 lines of output]
      openexr_skbuild_plugin: Computing OpenEXR version from CMake...
      openexr_skbuild_plugin: Computed version: 3.2.4
      *** scikit-build-core 0.8.1 using CMake 3.30.1 (wheel)


中略      
      -- clang-format not found.
      CMake Error at CMakeLists.txt:168
```

## トラブルの一部
clang-format がインストールされていることが前提になっていた。

## 解決方法
```
apt install -y clang-format
```

## 結果
```
-- clang-format found: /usr/bin/clang-format
```
となって、その部分のエラーはなくなった。
はじめてのオフライン勉強会！Gitの知識０から学んだこと

## はじめに
エンジニアをつなぐIT勉強会支援プラットフォームconnpassにて募集されていたオフラインの勉強会に参加しました！(勉強会に参加するのははじめてなのでドキドキしています。）
この記事では勉強会で学んだGitについてのアウトプットをします。
（記事を投稿するのをすっかり忘れていた...反省反省）

https://primeanswer.connpass.com/event/318268/

## 勉強会参加前のGitに対する理解レベル
Git？Githubのことすらあんまり良くわかっていないけど、同じじゃないの？
ブランチ？リポジトリのクローン？プッシュ？
分からないフレーズばかりでもう僕の心はポッキリ折れそうだよ！~~(ブランチ(枝)だけにねﾌﾌｯ😏)~~

## Gitとは
一言で言うと**ソースコード,デザイン,テキストなどのデータや変更履歴を管理するためのツール**であり、一度編集したファイルを過去の状態に戻したり、編集箇所の差分を表示したりすることができます。
Gitを用いることで共有ストレージ上のファイルを共同で編集する場合、知らず知らずのうちに他人の編集内容を上書きしてしまうといった失敗が起きず、**チームでの共同開発を効率化できる**ようになります。
...なんとなく分かったかも！

参考記事

https://www.kagoya.jp/howto/it-glossary/develop/git/?gad_source=1&gclid=CjwKCAjwmrqzBhAoEiwAXVpgoptOQC3OJ-OH74-gFrFAIFNy8l0e2ExTdzcurNGFQ3qpO0qrno7NuhoCeukQAvD_BwE#

https://backlog.com/ja/git-tutorial/intro/01/

https://qiita.com/matsu_aki/items/58dfff4efa5000947dae

## 分からないフレーズの理解
勉強会では分からないことをその場で質問する勇気がなかったので,単語を逐一調べながらお話を聞いていました。正直,実際にGitを使ってみるまでは言葉の意味がよく分かっていない状態だったと思います。

#### ブランチ
1つのプロジェクトから分岐させることにより、プロジェクト本体に影響を与えずに開発を行える機能のこと

#### リポジトリ
ファイルや変更履歴を保存しておくデータベースのこと。

#### コミット
ファイルや変更履歴をリポジトリへ登録すること

#### プッシュ
コミットを、ローカルリポジトリからリモートリポジトリへ反映させること。
プッシュを行うことで、ローカルリポジトリ上のファイルや変更履歴が、リモートリポジトリへアップロードされる。

#### プル

リモートリポジトリから最新の状態をローカルリポジトリに反映するコマンドのこと

#### クローン
リモートリポジトリを自分のローカルリポジトリに複製すること




参考記事

https://www.kagoya.jp/howto/it-glossary/develop/git/?gad_source=1&gclid=CjwKCAjwmrqzBhAoEiwAXVpgoptOQC3OJ-OH74-gFrFAIFNy8l0e2ExTdzcurNGFQ3qpO0qrno7NuhoCeukQAvD_BwE#

https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%A9%9F%E8%83%BD-%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%81%A8%E3%81%AF

https://qiita.com/matsu_aki/items/58dfff4efa5000947dae

https://www.sejuku.net/blog/71071

https://tech-blog.rakus.co.jp/entry/20220805/git

## 実際にGitを使ってみよう！

勉強会ではDocker上でGitを動かし,GitHubにプルリクエストを送るところまで行いました。





## 勉強会の感想
幅広い年代の方が参加している印象でした。（学生が僕含めて２人しかおらず,他は社会人の方でした）
周りに頑張っているメンバーがいた分,独学でやる時よりも明らかにモチベーション高く取り組めたので本当にありがたい体験だったな〜と思います。

## おわりに

勉強会の主催者の方に以下のサイトを紹介していただきました。
一言で言うと**エンジニア向けの報奨金付きQ&Aサービス**らしいです。
興味があればぜひご利用ください。

https://primeanswer.jp/
useSWRのfetcherをuseCallbackでキャッシュする

## はじめに
この記事では、useCallbackフックとuseSWRを組み合わせて、Reactアプリケーションのデータフェッチを最適化する方法を紹介します。

## そもそもuseCallbackとuseSWRって誰？
### useCallback
useCallbackフックは依存配列に含んだ値が変更されたときにのみ関数を再作成するためのHooksです。これにより、不要な関数の再定義を防ぎます。

### useSWR
useSWRは、Reactでデータのフェッチとキャッシングを簡単に行うためのHooksを提供するライブラリです。
フェッチしたデータのキャッシュや、古くなったデータを自動でフェッチしてくれたり、他にも色々な便利な機能を提供してくれます。

## 実装例の解説
以下のコードは`useCallback`と`useSWR`を組み合わせて、データ取得部分を実装しています。

### fetcher関数の定義
ここでは、`useCallback`内でfetcher関数を定義することでメモ化し、依存関係（`integration`と`date`）が変更されたときのみ再作成されることを保証します。
```javascript
const fetcher = useCallback(async () => {
  // データ取得
  const getData = (
    await fetch(`/analytics/${integration.id}?date=${date}`)
  ).json();

  return getData;
}, [integration, date]);
```
### useSWRによるデータフェッチ
useSWRを使用してデータフェッチを管理し、キーとメモ化されたfetcher関数で設定します。
```javascript
const { data } = useSWR(`/analytics-${integration?.id}-${date}`, fetcher, {
  refreshInterval: 0,
  refreshWhenHidden: false,
  revalidateOnFocus: false,
  revalidateOnReconnect: false,
  revalidateIfStale: false,
  refreshWhenOffline: false,
  revalidateOnMount: true,
});
```
`useCallback`で`fetcher()`関数をラップすることで、その依存関係（`integration`と`date`）が変更されたときのみ再作成されることを保証します。
fetcher関数のメモ化により、`useSWR`はfetcher関数がintegrationまたはdateが変更されない限り変更されていないと認識し、不要な再フェッチを防ぎます。

## useCallbackなしの場合の問題点

### Reactにおける関数の参照
Reactでは、コンポーネントが再レンダリングされるたびに、その中で定義されたすべての関数が再作成されます。
つまり`useCallback`を使用しないと、再レンダリングごとに新しいインスタンスのfetcher関数が作成されます。

### useSWRへの影響
`useSWR`はデータを識別するためのキーと、fetcher関数の参照に依存しています。
参照が変わると`useSWR`はfetcher関数のロジックが変更されていなくてもデータを再フェッチする必要があると解釈する可能性があります。

```javascript
const fetcher = async () => {
  // データ取得
  const getData = (
    await fetch(`/analytics/${integration.id}?date=${date}`)
  ).json();

  return getData;
};
```
上記の実装の場合、再レンダリングごとに新しいfetcher関数が作成されます。
その為`useSWR`は毎回異なる関数参照を見てしまい、`integration`やd`ate`が変更されていなくても不要な再フェッチが発生する可能性があります。

## まとめ
### 重要ポイントの復習
- useCallbackは関数をメモ化し、不要な再作成を防ぐ。
- useSWRはデータフェッチを管理し、関数参照の安定性に依存する。


## 最後に
`useCallback`と`useSWR`を組み合わせることで、React製のアプリケーションのデータフェッチを最適化し、パフォーマンスを向上させることができます。
初めて校正をするとき意識すること

## 初めに
私の業務内容に校正作業というものがあります。この校正作業を行い始めたのは今年の7月からでした。今回は私が初めて校正をして、気を付けたことなどをお話ししたいと思います。

## 校正とは
校正といわれると聞きなれない単語でしっくりこないかもしれませんが、やることは出来上がった原稿の文章を読んで誤字脱字がないかを探すことです。

## 校正の基本

・誰が見てもわかるように指示出しする
	修正箇所と修正してほしい内容がひと目でわかるように書き込む必要があります。そのために共通の手段として校正記号というものが用いられています。

・修正指示は赤字
	校正指示の記入は赤色を使用するルールがあります。ただし、赤色を使うのはあくまでも目立たせるためなので、修正以外のコメントで真っ赤になってはかえって見落としが生じてしまします。修正内容を補足する説明や補助的な指示などは別の色で記載します。

・余白に書く
校正において、修正指示は目立たせないといけません。修正箇所から近くの余白まで赤い線を引き出し（引出し線といいます）、その先に校正記号を書き入れます。該当箇所の先頭と最終文字に赤の斜線を引き、間の文字に横線を引くのが基本ですが、文字範囲がわかりやすいよう囲んでも大丈夫です。

## 最後に
私は校正作業の初心者です。当記事は初心者が一番最初に覚える基本を書きました。今後は記事中で出した校正記号の説明などもしていけたらと思います。

以上大野でした。