OmniAICreator/Qiita-1.07M huggingface dataset:
【TS】Promiseのメモ

## 考え方
- `new Promise`が実行した時点で、Promiseの中の処理は開始している。
- Promiseが実行した処理の結果や、終わったことを知りたいなら`then()`や`catch()`が必要。
- `then()`や`catch()`があってもなくても、Promiseの中の処理自体に影響はない。
- 非同期処理の完了を待ちたいなら、`then()`や`catch()`が必要。つまり、`then()`や`catch()`は非同期処理を同期処理として扱えるようにできる。



## new Promiseが実行した時点で、Promiseの中の処理は開始している
```typescript:同期と非同期が混在
console.log("001");

setTimeout(() => {
  console.log("002");
}, 2000);

console.log("003");

// 001
// 003
// 002
```

### 出力順を連番にする記述

```typescript:①Promiseを使う
console.log("001");

new Promise<void>((resolve, reject) => {
  setTimeout(() => {
    console.log("002");
    resolve();
  }, 2000);
}).then(() => {
	console.log("003");
});

// 001
// 002
// 003
```

@shiracamusさんにアドバイスいただいた内容を追記させていただきました。

```typescript:②async awaitを使う
async function main() {
  console.log("001");
  await new Promise((resolve) => setTimeout(resolve, 2000));
  console.log("002");
  console.log("003");
}
main();

// 001
// 002
// 003
```

### いけると思っていたけどうまくいかなかった記述

```typescript: いけると思っていたけどうまくいかなかった記述
console.log("001");

const promise = new Promise<void>((resolve, reject) => {
  setTimeout(() => {
    resolve();
  }, 2000);
});

// then()の部分だけ外だし
promise.then(() => console.log("002"));

console.log("003");

// 001
// 003
// 002
```

```typescript
// これはpromiseの中の処理が"終わった後にやることを定義している"だけ。
// then()は非同期処理を待たせることはできない。
promise.then(() => console.log("002"));
```


## async/awaitについて

### asyncで定義すると戻り値はPromiseになる
```ts
// () => Promise<void>
const asyncFoo = async () => {};

// () => Promise<string>
const asyncApple = async () => "apple";

// () => Promise<never>
// neverは例外を返す関数の戻り値の型
const asyncError = async () => {
  throw new Error("err");
};
```
Docker、はじめてみました (Part 2)

Docker、はじめてみました (Part 1)の続編です。
※ 本記事ではWindows WSL2上の説明をしていますが、基本的にMacでも使えます

## 本記事で目指すところ
実際にdockerfileを作成し、イメージ作成とコンテナ作成を行います。
今回はR Serverを立ち上げることを目指します。

## dockerfileの作成
R-v4.4.2
```plaintext:plaintext
# ベースイメージとしてRとRStudioを提供するrocker/rstudioを使用
FROM rocker/rstudio:4.4.2

# 必須システムライブラリをインストール
RUN apt-get update && apt-get install -y \
    libglpk40 \
    libglpk-dev \
    && apt-get clean && rm -rf /var/lib/apt/lists/*
```

## Dockerイメージの作成
作成したDockerfileがあるディレクトリに移動しておく
```zsh:zsh
docker build \
> -f <Dockerfile名> \
> -t <Dockerイメージ名>:<Tag名> \
> .
```
※Dockerイメージ名とTag名は管理しやすいようにしておきましょう！

## Dockerコンテナ作成
この部分が今回の肝です
```zsh:zsh
docker run \
> --name <Dockerコンテナ名> \
> -p 8787:8787 \ # この部分でポートを割り当てている
> -e PASSWORD=<パスワード> \ # R Serverログイン用
> -v /home/<ユーザー名>/<マウントしたいディレクトリ>:/home/rstudio/<マウントしたいディレクトリ> \
> -d <Dockerイメージ名> \
> /init
```
**ポイント**
-v引数：Dockerコンテナ内の/home/rstudioがR Serverのデフォルトワーキングディレクトリ
-d引数：-tや-itだとローカルのターミナルが使えないのでバックエンドでコンテナ作成

## Dockerコンテナ起動
```zsh:zsh
docker start <コンテナ名>
```
http://localhost:8787/ にアクセスするとR Serverが立ち上がっている
→ filesにマウントしたローカルフォルダが出てきます！

## 余談-1
R Serverは1時間放置すると勝手にサインアウトします
1時間以上かかる処理なんてざらにあるのでこれは由々しき事態です
というわけで同じく困っていて方がいたので以下URLに回答がありました
https://forum.posit.co/t/signed-out-due-to-inactivity-r-studio-server-open-source-version/91105
ローカルの /etc/rstudio/rserver.conf に下記を記載しましょう！
```plaintext:/etc/rstudio/rserver.conf
# Inactivity Timeout
auth-timeout-minutes to 0
```
これで安心して放置できますね～

## 余談-2
せっかくなので、GitHubレポジトリにDockerfileをpushしておく
※Dockerイメージの配布も良いですが、私が良く使う環境はサイズが大きいのでDockerfileの共有としています
```zsh:zsh

```

## 余談-3
```zsh:zsh
# Dockerイメージの扱い
docker image # 一覧表示
docker rmi <イメージ名> # 削除

# Dockerコンテナの扱い
docker start <コンテナ名> # 起動
docker stop <コンテナ名> # 終了
docker ps # 一覧表示
docker rm <コンテナ名> # 削除
```
※docker rmiは紐づいているコンテナを削除しないと使えない T_T

# 最後に
-v, -d引数あたりが難関だったなあ～
Part 3ではPython環境整えてみます

:::note info
**この時点で知っておくべきTipsや基本的内容があればぜひコメントください！**
:::
Claudeを使って勉強した話(k8s編)

この記事は[Hacobu Advent Calendar 2024](https://qiita.com/advent-calendar/2024/hacobu)の6日目の記事です。

# はじめに

こんにちは、あしゅりーです。
普段はテクノロジー本部に所属し、バックエンドエンジニアをしてます。

今回はKubernetesをお試しで使ってみる過程でどういう風なことをしていたかを書いてみようと思います。
 
# k8sを試すところでコケ続けていた

　弊社ではマイクロサービスアーキテクチャを採用しており、その基盤技術としてKubernetes（以下、k8s）が重要な役割を果たしています。日々のバックエンド（サーバーサイド）開発においてk8sに触れる機会は多いものの、これまでは感覚的な理解に留まっていました。個人的な興味もあり、より深い技術理解を目指すことにしました。

　まずは簡単化のためにGolangで作成したAPIサーバーをデプロイしてみようと考え、Deploymentを書いていたのですが、これがなかなかうまくいきませんでした。またWeb検索でのトラブルシュートをしてみるもうまく情報をヒットさせることができず、この状況を打開できていませんでした。

　そこで今回はClaude（Claude 3.5 Sonnet）にテキストコミュニケーションを行うことで解決が図れないか試してみることにしました。

# 困っていたこと

時系列の要素もあるのですが、大きく分けて以下の4つの点で困っていました。

- Deploymentにおける必要なもの、不必要なものの判断がつかない
- デプロイを試みても失敗してしまうが、トラブルシュートの方法を知らない
- ログの意味を理解できない
- デプロイされたアプリに対してリクエストを飛ばせない

# 実際にAIに聞いてみた

　いくつか実際の例を載せてみたいと思います。

　まずは、エラーの原因とトラブルシュートの方法について聞いてみました。ちなみに[go-task](https://taskfile.dev/)というものを使ってkubectl系のコマンドはまとめています。go-taskはGolang製のタスクランナーで、makefileのような機能をYAML形式のファイルで実現できるツールです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3145704/3f6cf892-cfab-3625-9e1c-386ba018844f.png)

エラーの内容が見切れているので載せておきます。

```
task: [k8s:deploy] kubectl apply -f deployment.yaml -n ashlius
Error from server (NotFound): error when creating "deployment.yaml": namespaces "ashlius" not found
Error from server (NotFound): error when creating "deployment.yaml": namespaces "ashlius" not found
task: Failed to run task "k8s:deploy": exit status 1
```

![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3145704/6bda0818-2624-4e1b-2941-155b73699101.png)

　全て載せるとすごい長さになってしまうので省略しますが、namespaceが作成されていないことを確認できました。結論から話すと原因はgo-taskのyamlでインデントが一つだけずれていることにより、namespaceを作成するコマンドが正しく実行されていなかったことでした。この辺も逐一Claudeにファイルを共有してみてもらいました。

　次はアプリのデプロイには成功して実際にリクエストを飛ばしてみようとしたところ、レスポンスを得られなかった件を相談しています。

![image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3145704/8603593b-bcbb-eadd-9fac-5d3fa4906e29.png)
![image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3145704/2fee39ac-7386-d637-189a-c241532be594.png)

　トラブルシュートの過程で、minikubeのtunnelという機能が便利ということで、そちらを利用してk8sにデプロイしたアプリに対してリクエストを送ることができました。なおtunnelという機能があることを知ったのはClaudeが教えてくれた要素です。

# まとめ

　初めて触れる技術などをライトに試すといった観点で、AIに助言を求めてみるのは良い選択だったと思っています。具体的には以下のような良かったなと思うポイントがありました。

- トラブルシュートのための情報を集める手段を提案してもらえる
    そもそも情報の集め方を知らなければエラーの解決が難しいです

- 原因を示していそうなログの探索を手伝ってもらえる
    情報があっても原因を示していそうなログがどれか判断がつきづらいです

- 普遍的なワードだが実は専門用語だった、というワードに気づける
    例えば、k8sだと「Service」（サービス）
    
    > KubernetesにおけるServiceとは、 クラスター内で1つ以上の[Pod](https://kubernetes.io/ja/docs/concepts/workloads/pods/)として実行されているネットワークアプリケーションを公開する方法です。

    引用元：https://kubernetes.io/ja/docs/concepts/services-networking/service/

- Claudeの出力の裏取りが格段に早くなる
    Claudeの出力で使われるワードを見て、正しい用語でWeb検索できるようになります

もし触ってみたい技術があるんだけど、うまくいかないな〜という場合には、こういった対処の方法もあるということで覚えておいていただければと思います。
コンピューターの思考

# はじめに
[CYBIRD Advent Calendar 2024](https://qiita.com/advent-calendar/2024/cybird "CYBIRD Advent Calendar 2024")の9日目担当の@CN_30371500です。
今年2024年の新卒として入社し、現在はイケメンシリーズの主に２つのタイトルの品質管理をしています。
8日目は@kyorokyoroさんの[Firebaseイベントの登録からBigQueryでのデータ取得まで](https://qiita.com/kyorokyoro/items/8ae5118df73adb29492a "Firebaseイベントの登録からBigQueryでのデータ取得まで")でした。
私自身が現在エンジニアとして稼働していないのと、初めて書く記事ということもあり、超入門編コンピューターの思考について書いてみました。

# コンピューターの思考とは
まず、コンピューターの思考とは何かということについてですが、簡単に言うと人間がどう動くか決めるまでに行われる思考のコンピューター版です。
人間は生きているうちに数々のことを自然に行っていると思うのですが、それには無意識的に行っている思考があります。

#### 人間における具体例（歯磨き）
例えば歯磨きをするために（私の場合）
洗面所のドアを開ける→洗面所の電気をつける→髪をまとめる→歯磨き粉を手に取る→歯磨き粉の蓋を開ける→歯ブラシを手に取る→歯磨き粉を豆ほどの量を歯ブラシのブラシ部分に着ける→歯磨き粉の蓋を閉める→歯磨き粉を元の位置に戻す→歯ブラシですべての歯を磨く→コップに水を汲む→コップの水を口に含んでゆすぐ→水を吐き出す→歯ブラシを洗う→歯ブラシを元の場所に戻す→コップを軽くゆすぐ→コップを元の位置に戻す
という行動をとります。

若干の違いはあれど、人間が歯磨きをすると大体上記の通りの手順で行うことが多いと思います。
ですが、5行にもわたる作業を行っているにもかかわらず、人間同士で話す時は「歯磨きをしてくる」と言えば上記の手順を行っているであろうことが大体想像できます。
ですが、コンピューターは与えられた命令通りにしか動けません。

#### コンピューターにおける具体例（水を注ぐ）
コンピューターにペットボトルの水とコップを渡して、水を注いでくださいと命令します。
すると、「与えられた情報だけでは水を注ぐことはできません。」という返答が返ってきてしまいます。
なので、コンピューターに水を注いでくださいと命令するためには
渡したペットボトルの蓋を開けて、"ペットボトルの水"を"渡したコップ"に"コップの半分ほどまで"注いでくださいと命令してやっとコンピューターは水を注ぐことができます。

上記ではペットボトルの水とコップを渡していますが、本来はキッチンの冷蔵庫の扉裏にあるペットボトルの水と食器棚に置いてあるコップをとって来てという部分も追加するべきですね。
つまり、人間とコンピューターはとてもローコンテクストな会話をしないといけないのです。

## 結論
以上でコンピューターはどのような思考をするかについて解説できたのではないかと思います。
プログラミングを学び始めたころ、自分がコードを書く上で一番多かったのはコンピューターの挙動の予測ミスによるエラーでした。コンピューターの挙動を予想するためにはコンピューターの思考を理解することが一番重要だと思います。
なので1人で開発をする時に限らず、複数人で開発をする際も、エラーが出てしまった時は一度どのような命令をコンピューターに出しているかを整理してみるとエラーの原因がわかりやすいのではないかと思います。

# おわりに
今回はコンピューターの思考を人間に例えて解説してみました。
次の機会にはもっと技術的なことを記事にできるように日々アンテナを張って過ごしたいと思います。

[CYBIRD Advent Calendar 2024](https://qiita.com/advent-calendar/2024/cybird "CYBIRD Advent Calendar 2024")　10日目は、@I_am_bakenekoさんの[【検証】10日間、生成AIに専属の絵の先生をしてもらったら。](https://qiita.com/I_am_bakeneko/items/c20f0a6a48b316000b21 "【検証】10日間、生成AIに専属の絵の先生をしてもらったら。")」です。
お楽しみに！
自動テスト導入の思い出、そして教訓

霜寒の候、みなさま自動テストの導入状況はいかがでしょうか。

かつては私も自動テストの効果に懐疑的でしたが、今では未導入の開発プロジェクトに参加すると、風邪をひいてしまいそうになります。

ところでここ最近の私の周りのプロジェクトでは、自動テスト導入の効果について論じることは少なくなってきたと思います。しかしそれは自動テストをしないということではなく、既に設計、実装、検証といった開発活動の一環であり、逆に自動テストを書かない理由を問われるほどです。

今回は自動テストの「自の字」も知らないところから、後輩たちが自然と自動テストまで書き上げてプルリクを上げてくれるような開発チームになったところまで、私の歴史を振り返ってみたいと思います。

ということで私もアドカレの仲間に入れてください。

## 太古時代 (10年以上前)
私がまだピヨピヨだった頃です。

リポジトリへのコミットが厳しく、とても厳しく制限されていた時代がありました。この頃、テストはすべて手動で行い、テストケースはExcelで毎回作成し、計画と実施結果はそれぞれレビューを受け承認を得る必要がありました。

丁度この頃弊社では機能安全を意識した開発プロセスが始まり、またそれをターゲットとしたテストツールの開発も行われ、いわゆるガチガチのウォーターフォール開発プロセスでした。

しかしテストプロセスに関してはまだまだ未熟で、過去のテストを使い回すことなど稀でした。

## 古典時代 (10年くらい前)
個人的にこのやり方では限界を感じ、当時は「リリースする製品に組み込むコードじゃないから」とかかなり色々な理由を付けて、自動テストをリポジトリに追加するようになりました。しかし、この自動テストは完全に自分用であり、そもそも自動テストという考え自体、社内での認知度は高くはありませんでした。

CI環境もまだ整備されていなかったため、効果は限定的でしたが、自動テストという考え方を周囲に発信し始めた時期でもあります。

まだまだ孤軍奮闘状態です。

## 中世時代 (8年前)
このころ、主に弊社がターゲットとしている組み込み業界において、テスト自動化が目に見えて盛り上がり始めたように思います。私の会社もテストツールベンダーであったため、この話題で声がかかる機会が増えました。

一方で、社内では単体・結合・システムテストを厳格に分類するプロセスが足枷となり、テスト自動化の本質を見失いがちでした。自動テストツールがよく「ユニットテストツール」と呼ばれていたこともよくなかった気がします。仕様ではなくコードのカバレッジ100%を目指すことが目的化してしまい、結果として実装のマズいコード修正に伴いテストも大量に破棄したこともありました。振り返れば「アンチパターン」を学びたければここに来いと胸を張って言えるような時代でした。暗黒時代です。

## ルネサンス時代 (6年前)
この時期、自動テストはコードではなく「仕様」に向かって書くものだと認識を改めました。それまでの経験を踏まえ、実用的で維持可能なテストコードを書くことを目標に切り替えていきました。すべてを自動化するのではなく、ある意味で肩の力を抜いて、手動テストの良さにも目を向け、自分たちにとって無理なくメリットのある自動テストを考え始めました。

この頃に作ったテストの多くは、現在でも稼働しており、自動テストが価値を生む基盤が築かれた時期だったと感じています。

## 産業時代 (5年前)
社内でのテスト自動化の文化を広げるため、地道な努力を重ねました。私が色々な開発プロジェクトに直接入り込み、テストコードやCI環境を整備し、その実行手順を簡略化したドキュメントを作成しました。テストの書き方がわからなければ、テストやテスタビリティのあるコードをペアプロ的に書いて見せたりもしていました。

さらに、レビューではテストの目的や効果について周知し、成功事例が出たときには大げさに喜ぶよう心がけました。

## 現代 (2年前～)
今では、開発チームのメンバーが私の指導がなくても自動テストを書いてくれるようになりました。さらには、私が見落とした不具合を後輩たちが書いたテストが発見してくれることもあります。

自動テストが特別な作業ではなく、日常の一部として定着したことを実感しています。この歴史を振り返ると、技術的な進化だけでなく、文化や意識の変化も大きな鍵だったと思います。

## おわりに
私の自動テスト導入の旅路はとても泥臭く、失敗と試行錯誤の連続でした。しかし、その過程で得た経験と成果は、今の私の開発スタイルを支えています。

これから自動テストを導入する方への銀の弾丸というか効果的なプラクティスを案内することはできませんが、次のような教訓を残すことはできるかもしれません。

- 自分たちの組織やチームの規模で、無理のない自動テストの作り方を決める。
- 継続的に、開発メンバーに対してコンサル的なことを行っていく。
- 導入で満足せず、効果をメンバーや関係者に発信していく。

みなさんも自動テストを定着させる道のりを、上手く進んでいけることを願っています。
rails newした後、git hubで管理できるようにする方法

初めまして。未経験エンジニア転職を目指しているりんころです。
今回は、『rails new』した後に、そのコードをgit hubで管理できるようにする方法を記事にします。

# 記事にした理由

自分が個人開発を始めるときに、ローカルでrails newしたわいいものの、それを、リモートリポジトリと反映させるやり方がわからず、手こずったので、やり方をまとめてみました。

## **1.リモートリポジトリを作成**
git hub内で、新規リポジトリを作っておいてください。

## **2.ローカルリポジトリを作成**
1. ローカルで『rails new』実行


## 3.ローカルリポジトリをリモートに送り込む準備
以下を、作ったアプリのディレクトリに移動して、実行してください

```
$ git init #local ripositoryが作成される。

$ git add .
 
$ git commit -m ”どんな機能を実装したのか等のコメントを残す”  
 
```

## 4.リモートリポジトリに送り込む

```
git remote add origin リモートリポジトリのURL #送るリモートリポジトリを指定しています。

git push origin HEAD
```
これで、さっき作ったリモートリポジトリにローカルの内容が反映された状態になります。
JAWS-UGに参加して人生変わった件 ～印象深いイベントを紹介していくよ！～

# はじめに
皆様、こんにちは！
JAWS-UG (Japan AWS User Group)参加していますか？

JAWS-UGの説明は割愛しますが、私は2023年頃からJAWS-UGに参加して、かなり人生変わりました。
今回は、JAWS-UGの数あるイベントの中でも<font color="red"><b>「あー！人生観、変わったわー！あー！変わったわー！」</font></b>的なイベントを独断でご紹介します！

https://jigokuno.jugem.jp/?eid=1008


# 人生観変わったランキング
それでは、ランキング形式で行くよー！

https://jigokuno.jugem.jp/?eid=1004


## 3位　JAWS FESTA 2024@広島
直近で参加したJAWS-UG２大イベントの１つです。
JAWS-UGではJAWS Days（＠東京）とJAWS FESTA（＠地方）がそれぞれ年1回ずつ開催されます。

JAWS FESTAではKeyNote直後のとても良い時間帯に登壇させていただ気、聴講された方からもリアクションやご質問いただけたので、とても思い入れ深いです。

https://speakerdeck.com/yukiogawa/sheng-cheng-ainiyoruye-wu-li-huo-yong-apuriwo-bu-men-heng-duan-timuga3ri-depocwozuo-tutemita

また、前夜祭でもLT発表させていただきました！
こちらは会場の雰囲気がクラブっぽい感じでしたが、ノリだけで発表しました。

https://speakerdeck.com/yukiogawa/awskomiyuniteibirudaninaritainziya

登壇すると懇親会でも多くの話しかけていただけるので、ネットワーキングの点でも非常に有利です。
お陰様で色々なお話（講演への登壇のお誘い、企画中のJAWSイベント情報など）が聞けます。

<font color="red"><b>「アウトプットする人に情報は集まる」</b></font>と以前教えていただいたことがありますが、まさにその通りかと思います。


## 2位　Bedrock Claude Night@AWS Startup Loft Tokyo
今やJAWS-UGの中で最も活発と言っても過言ではない、AI/ML支部の<font color="red"><b>第1回Bedrock Claude Night</b></font>に参加させていただきました。

実はLT応募した時にはまだネタが全く決まっておらず、発表時にも成果はほとんどなかったのですが、無事発表だけは乗り切ることができました。

https://speakerdeck.com/yukiogawa/bedrock-claude3woshi-tuteshi-chang-dui-ying-wodxhua-wojian-tao-sitemita

ただ、他の人の発表を見るとかなり生成AIモデルやBedrockアーキテクチャの話をされていたので、**「もっと頑張ろう！」**とモチベーションに火をつける機会となりました。

また、本会でも@minorun365さんや@yoshidashingoさんや@Naoki_Ishiharaさんや@schronekoさんを始めとしたAI/MLをリードされている方々とお話でき、とても楽しい時間を過ごせました。

（ちなみに、本来はAnthropicの方々も来日して参加される予定でしたが、急遽不参加に・・・）


## 番外編　re:Invent2023＠Las Vegas
re:Invent2024はもちろん人生観が大きく変わったイベントではあるのですが、金銭面での参加の敷居が高い、JAWS-UGのイベントではないので番外編としました。

圧倒的なスケール（数、広さ！）で展開される各セッション、アーティストを巻き込んだKeyNoteの演出、Expoでもらえる豪華なSWAG、re:Playや5km Runなどの遊び心のあるイベント、などギュギュッと４日間に詰め込んだ世界規模のイベントです。

参加チケットだけで約20万円なのでフライト＋ホテルで100万円以上かかってしまいますが、その分の価値は十分あるおと思います。
今年2024は行けなかったので、来年こそは行けるように頑張りたいと思います。
（主に、上司の説得や外堀の埋め方などの政治的な活動が必要ですね）


## 1位　JAWS Days 2024@池袋
先ほど紹介したJAWS FESTAと並ぶJAWS-UG２大イベントの１つです。
2024年度のJAWS Daysは2024年2月に開催され、2024年に登壇などの活動を実行できた最初のきっかけとなります。

ここで@minorun365さんのこちらのセッションに参加したことで、**「自分でも生成AIの活用を真剣に考えなくては！」**と考えるようになりました。

https://qiita.com/minorun365/items/24dfb0ea3afde6ed0a56

また、本会も終わった後に社内メンバーでウロウロしていたところ、AWSの方や@minorun365さんと一緒に懇親会に参加することができました。
ここの懇親会をきっかけに別の社内メンバーが@minorun365さんが運営のJAWS-UGで登壇できたので、ネットワークを活用したアウトプットの流れできてきた、と言えます。

なので1年を振り返ると、**この時に知り合えた人とその後も継続交流でき、色々な場での自分がアウトプットする機会、または自分が社内で立ち上げたコミュニティの勢い**にも繋がってきています。

社内コミュニティの話はこっちで書いています。

https://qiita.com/_YukiOgawa/items/3f60789a99f2c8e247fc


# 最後に
自分の中でJAWS-UGを始めとしたコミュニティは、「登壇してアウトプットだけして終わり！」というわけではなく、<font color="red"><b>アウトプットの後のネットワーキング（人との交流）が非常に大事</b></font>だという結論になりました。


今後もしJAWS-UGにご参加される方がいらっしゃれば、お気軽にお声がけください。
また、登壇のお誘いやイベント企画なども積極的に携わっていきたいと思いますので、ぜひよろしくお願いいたします。
小数を含む計算時に発生するバグ

業務にて詰まった部分とその解決方法を簡単に紹介

## 発生した問題

不特定数の値のリストを全て加算するという処理を実行する場合なんかに``fold``を使うことがあるかと思います
例えば、以下のようなリストがあったとします
```dart
final sumValueList = [1, 2, 3, 4, 5];
```
これを全て加算した結果を取得したい場合は``fold``で以下のように記述します
```dart
final result = sumValueList.fold<int>(
  0, (previousValue, element) => previousValue + element
); // 15
```
とまあ普通に使う分にはただ便利なだけで何ら問題ない``fold``ですが、小数を含む計算をしていた時に問題が発生しました

その時に計算した値と結果は以下の通りです
```dart
final sumValueList = [99, 1.9, 1.9, 1.3, 1];

final result = sumValueList.fold<double>(
  0, (previousValue, element) => previousValue + element
); // 105.10000000000001
```
めっちゃ桁が増えました

原因はシンプルに浮動小数の計算における仕様です
詳しくは解説しませんが、小数ごとのズレが累積していった結果表面化したのが上記の結果になります

## 解決策
この現象自体はどうしようもないので、発生した後に対処する必要があります
小数なので四捨五入するなりすれば解決しそうですが、今回実装していた仕様だと「小数第一位までの値を取得して表示する」というものなので、下手に計算を追加して結果が変わるようなことがあったら面倒なことになってしまいます

そこで役に立つのが``toStringAsFixed``です

これは小数を指定した桁数までで固定するといった挙動を実現してくれます
使い方は先ほどの計算結果の最後に付け加えるだけです
```dart
final sumValueList = [99, 1.9, 1.9, 1.3, 1];

final result = sumValueList.fold<double>(
  0, (previousValue, element) => previousValue + element
).toStringAsFixed(1); // 105.1
```
表示したい部分まで取得することができました

小数の加減算を実装するときは、結果におかしなことが起きていないかを気をつけましょうという話でした
重い腰、上がる

初めまして、雑魚エンジニアの稚魚と申します。
諸々自分の記録を残してやろうと思い始めました。前々からやってみたかったんですよね。

# おもろいやん

へえこれがマークアップ記法ですか。なかなかやりますね。
こんな風にブログ的な何かを書くのなんて初めてなので楽しいものです。
いつまで続くかとかいらん心配は置いといて、やるからにはある程度方針を決めたいと思います。

## 目的
まずこれだよね。なんでやるかってそりゃ残したくなったからですよ。
自分がやってきたこと一括で形として目に見えたらいいよねっていう。

多分あまりにも開始が遅いんだけど、まあ一番若いのは今だし？ノリだよノリ！(某273兄貴)

## 目標
いやそんなものないよね。残すことにゴールなんてさ。
でもまあ強いていえばというか別に強いることもないんだけど、成長したいですね。
かといって納得のいくようなスキルをつけたいとか言い出したら一生治ることのない病にかかってしまうので、当面は資格取得のためとしておきます。

## 経歴
ではここで不詳この稚魚の経歴をお見せしましょう。

--経歴--
無。

以上です。資格とかそんな立派なもん何一つ持ってません。
というわけで備忘録を残そうということですね。

## 目標(改)
零地点突破・改。かっこいいですよね。
というわけで沸々と湧いてきたやる気を目標という形にコンパイルしていきましょう。
言葉の意味なんていいんです。覚えたての言葉を言ってみたいだけですから。

まずは記事作成によって得られそうな恩恵として
・備忘録の一覧化
・文章能力の向上
・書き出すことによる自らとのケイヤク×ケイヤク
・た...タイピングスキル

この辺りでしょうか。

では取得したい資格の一覧をば。
・ITパスポート
・基本情報技術者
・Androidアプリケーション/プラットフォーム技術者

直近ではこの辺りを目標としていきたいと思います。

あ、今更ですが一応フロントエンドのアプリ開発をメインでやってきてます。
保有(笑)言語としては
・Java

そう、Javaのみ。てかこれすら怪しい。とにかくJavaで食っていけるようになりてえよ

## まとめ

つらつらと書きたいこと書きましたが、まあ端的にいえば自己満ブログです。みんなそうなんですかね。

さて、書いているうちにお昼になったのでいつものおサブウェイでも決め込みますかね。

ありがとうございました。
Googleカレンダーが見にくくなったので、カスタムCSSを導入した

# はじめに
いつぞやのアップデートで、Googleカレンダーのフォントが変わりました。  
また、ダークモードも導入されましたが個人的に暗すぎて見にくいです。

ということで、カスタマイズします。

# カスタマイズする

やることは至ってシンプル。  
Google拡張機能を作ります。

`manifest.json`で適用したいサイト（`https://calendar.google.com/*`）を指定し、自分で用意したCSSを割り当てます。

```json:manifest.json
{
	"manifest_version": 3,
	"name": "カスタムCSS",
	"version": "1.0.0",
	"content_scripts" : [
		{
			"matches" : ["https://calendar.google.com/*"],
			"css" : ["GoogleCalendar.css"]
		}
	]
}
```

あとは適当にデベロッパーツールでCSS変数名を確認しつつ、上書きしました。

```css:GoogleCalendar.css
body {
    --gm3-sys-color-surface-container-low: #e9e9e9!important; /* 外側部分の色 */
    --gm3-sys-color-surface: #f1f0ec!important; /* カレンダー本体の色 */
    --gm3-sys-color-surface-container-highest: #c8cace; /* 枠線の色 */
    font-family: monospace!important;
}
```

結果がこんな感じ。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603116/9647f13b-2255-a542-c337-6e282849fdb4.png)
（改めて見ると、カレンダーって機密だらけなのでほとんど載せられない。）

もう以前のフォントが思い出せなくて・・。  
ちょっと違う気がしますが、最新のやつよりかは多少見やすいので良しとします。  
（monospaceじゃなくてsystem-uiのほうが正解だった気もしました）

# おわりに
今回作ったものの`manifest.json`をいじることで、他のサイトでもカスタムCSSを適用出来ます。  
目を酷使する我々なので、よく使うサイトは目に優しいデザインにしたいですね。

```json:manifest.json
{
	"manifest_version": 3,
	"name": "カスタムCSS",
	"version": "1.0.0",
	"content_scripts" : [
		{
			"matches" : ["https://calendar.google.com/*"],
			"css" : ["GoogleCalendar.css"]
		}
		,{
			"matches" : ["https://Yahoo.co.jp/*"],
			"css" : ["Yahoo.css"]
		}
	]
}
```
建築システムのリニューアル現場から学ぶ、上流工程の重要性と実務のコツ

この記事は、[Lancers（ランサーズ） Advent Calendar 2024](https://qiita.com/advent-calendar/2024/lancers) の6日目の記事です。

# はじめに

こんにちは、ランサーズ株式会社でシステムインテグレーション事業に携わっている湯藤です！
私は現在、建築関連システムのリニューアルプロジェクトに参画し、主に上流工程を担当しています。本記事では、特にユースケース図とシーケンス図の作成に焦点を当て、現場での活用方法とその効果を共有します。

# 上流工程におけるユースケース図とシーケンス図の役割
上流工程では、要件の整理やシステム設計の方向性を明確にすることが最重要課題です。その中で、ユースケース図とシーケンス図は以下のような効果を発揮します。

###  ユースケース図：全体像を把握しやすくする
ユースケース図は、システムが提供する機能とそれを利用するアクター（人や他システム）を視覚的に整理するツールです。これにより、関係者間での共通認識が生まれ、漏れのない設計が可能になります。

https://it-koala.com/usecasediagrams-1832

###  シーケンス図：処理の流れを具体化する
シーケンス図は、システム内外のコンポーネントやアクターがどのように相互作用するかを時系列で表現します。これにより、設計の詳細化や問題箇所の特定が容易になります。

https://cacoo.com/ja/blog/what-is-sequence-diagram/

# 実務での活用事例
リニューアルの背景には必ず解決すべき課題があります。これを具体化することで、プロジェクトの方向性を明確にします。

###  ユースケース図の作成：設計フローの整理

工事発注～請求までを電子化したEDIシステムの現状分析作業の一環で、発注者、管理者、施工業者をアクターとし、それぞれの役割に基づくユースケース図を作成しました。

**主なユースケース**
* 発注者が図面等の工事資料をアップロードする。
* 管理者が図面をレビュー・承認する。
* 施工業者が承認済み図面をダウンロードする。

**効果**

* アクターごとの役割が明確化され、関係者全員がシステム全体像を理解しやすくなりました。
* クライアントとの認識のズレを防ぐことができました。


###  シーケンス図の作成：通知機能の設計

工事発注～請求までを電子化したEDIシステムの現状分析作業の一環で、工事資料が変更された際の「工事資料変更通知機能」のシーケンス図を作成しました。

**シーケンス例：設計変更通知**
* 設計者がシステムで図面を修正・保存。
* システムが変更を検知し、通知メッセージを生成。
* 管理者と施工業者に通知を送信。

**効果**

* データフローとタイミングが可視化され、開発チームが効率的に実装を進めることができました。
* 予期せぬ処理遅延やエラーが起きる箇所を事前に特定できました。

# まとめ：可視化が成功の鍵
建築関連システムのリニューアルプロジェクトでは、ユースケース図とシーケンス図が要件整理と設計の柱となりました。これらのツールは、上流工程における認識の統一や設計ミスの防止に不可欠です。

もし同様の課題を抱えている方がいれば、ぜひこれらの手法を取り入れてみてください。この記事が少しでも参考になれば幸いです！

# 最後に

10月からランサーズに入社しSESでクライアント先に入り込んで業務を進めるのは初めてでしたので、不安もありましたが何とか問題なく業務を進められております。今後は、フリーランスの方とチームを組んでプロジェクトに参画することが求められるので、上流工程の業務だけでなく開発能力向上させることを目標に行動していきます！


そんなLancersでは挑戦的な取り組みにも力を貸していただける、新しいメンバーを募集中です！

https://recruit.jobcan.jp/lancers01/list/all/all


<!---
# これまで
元請けのSI企業で主に業務系SEやテクニカルサポート業務の実施。また、自社サービスの開発会社でマネジメント、開発などを経験してきました。クライアントワークは慣れていましたが、SESとしてクライアント企業に入り込んでの業務経験はありませんでした。

# 自分の求められることを意識して業務を行う
私が現在携わっているSI事業は、今年、設立された事業部で、売上を0から作っていく必要がありますため、フリーランスの方たちとチームを組んで、プロジェクトに参画していくことが目標となっています。

チームを組んでプロジェクトに入る上で、クライアントとしてもリスクがありますので、まずはプロパーの社員など、少人数で案件に参画し信頼を勝ち取ることが重要になってきます。今回、携わっている案件にて信頼を勝ち取るために取り組んでいることについてご紹介します。

# 現在、携わっている案件
建築関連システムのリニューアルプロジェクトに参画しております。その中で、現行の建築関連システムの仕様、要求分析を行っています。いわゆる上流工程を担当しております。(テクニカルなことは担当していません。。)
-->
homeディレクトリを引越しする

### 環境
UbuntuのPCを使っています。
ホームディレクトリがいっぱいになってきたので、外付けSSDに引っ越しします。
今回は、ホームディレクトリについては内蔵SSDは使わずに完全に外付けSSDに引っ越しすることにします。

### やりたいことの絵
![スクリーンショット 2024-12-06 13.05.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149425/feca2a4a-f75e-b45c-ce93-4bc025e709b5.png)
内蔵SSDは500G、外付けSSDは2TBです。
外付けSSDは500G,500G,350G,350Gの4つに区切ってあり、1つ目をホームディレクトリにすることにします。

```sh
lsblk -t /dev/sda -o NAME,LABEL,SIZE

NAME   LABEL       SIZE
sda                1.8T
|-sda1 partition1  500G
|-sda2 partition2  500G
|-sda3 partition3  350G
`-sda4 partition4  350G
```


### 状況
LVGでルートボリュームを管理しています。
ホームディレクトリ用のパーティションは切っていませんでした。
/dev/sda1 が外付けSSDのパーティション1
/dev/mapper/ubuntu--vg-ubuntu--lv がルートボリュームデバイス

### 手順
```sh
1. 移動先デバイスをマウント
mount /dev/sda1 /mnt/partition1 # partition1を適当にマウント
```

```sh
2. 移動先デバイスにコピー
rsync -av /home/ /mnt/partition1 # homeディレクトリの中身を移動
```

```sh
3. 移動先デバイスをホームパスにマウントしてテスト
mount /dev/sda1 /home # ここで、動作確認
```
```sh
4. fstab更新して自動でホームパスにマウントされるようにする
LABEL=partition1 /home ext4 defaults 0 0 # LABELでなくuuidの方がよいかもしれない
```

```sh
5. fstabなどがうごくか動作確認のため再起動
sudo reboot
```

```sh
6. ログインして/homeディレクトリの動作確認
```

```sh
7. バックアップ(内蔵SSDのホームディレクトリ)を削除
mount /dev/mapper/ubuntu--vg-ubuntu--lv /mnt/root # 適当にマウント
sudo rm -rf /mnt/root/home/* # ホームディレクトリを削除(homeディレクトリを消してもよかったが、エラーが出た)
```

```sh
8. 最終形
$ df -h
Filesystem                         Size  Used Avail Use% Mounted on
/dev/sda1                          492G   61G  406G  13% /home
/dev/mapper/ubuntu--vg-ubuntu--lv  394G   16G  361G   5% /
```
### 感想
すっきりしていい感じ。
大好きなポケモンと一緒に仕事できる「vscode-pokemon」

[リンクアンドモチベーション Advent Calendar 2024](https://qiita.com/advent-calendar/2024/lmi)のエントリーです。

1年の集大成に何か立派な記事を書こうと思ったのですが、時間がありません💦

後輩には日々「立派なアウトプットなんてしなくて良い。まずはアウトプットすることが大事」と偉そうなことを伝えたりしています。その教訓に則って、めっっっちゃラフな情報を共有します。背中を見せます。休憩中にでも読んでもらえたら幸いです。

## 皆んなポケモンが大好き

何年経っても色褪せないコンテンツ、ポケモン。皆んなポケモンが大好きです。

そんなポケモンと一緒にコーディングができたら素敵ですよね？

できます🎉

[vscode-pokemon](https://github.com/jakobhoeg/vscode-pokemon)というVSCode拡張です。
自分はCursorにインストールして使っています。

![vscode-pokemon-light.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192435/32827268-12b1-7607-0571-b19282bd0aa1.gif)

VSCodeの左下に好きなポケモンを召喚（151匹のみ）できて、ホバーすると反応してくれます。

![スクリーンショット 2024-12-06 12.38.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192435/164e556f-56b6-03b1-1fd3-4464a3d38546.png)

すごく可愛くて癒されるので、おすすめです。
右下でうろちょろされても何故か気になりません。（自分はこういうの気になるタイプなのですが不思議です）

ちなみに[Product Hunt](https://www.producthunt.com/)のデイリーのランキングで見つけました。

## ライセンスとか大丈夫？

専門家でないので判断ができませんが、開発者も気を使っている部分ではありそうです。

[READMEのCredit](https://github.com/jakobhoeg/vscode-pokemon?tab=readme-ov-file#credits)を見ると、非商用のファンプロジェクトであり、ポケモンのイメージはニンテンドーやゲームフリークに帰属すると明記されています。

> Sprite Sources
Pokemon Sprites: © The Pokémon Company / Nintendo / Game Freak
The sprites are used for non-commercial, fan project purposes only
Original sprite artwork belongs to the respective copyright holders
Acknowledgments
All sprites are property of their original creators
This repository is a fan project and is not affiliated with Nintendo, The Pokémon Company, or Game Freak

[LICENSE](https://github.com/jakobhoeg/vscode-pokemon/blob/main/LICENSE)を見るとCC0ライセンスを適用し、以下が明記されていました。

- 画像コンテンツの権利は明確にポケモン社に帰属
- 拡張機能自体のコードはCC0で自由に利用可能
MLチームのチーム運営を改善しようとしている

スタンバイアドベントカレンダー2024の10日目です！

# 前置き
私は2024年4月1日にスタンバイに入社しました。
まだまだ社会人歴は3年目です。馬鹿が付くような正直さ（と、一応自然言語処理の研究で大学院を出たところ）に期待をかけてポテンシャルで採用してもらったという自覚があるくらい、ジュニアなエンジニアです。
なので、私自身はキャッチアップに半年も時間がかかり、下期になってやっと色々な面で貢献できるようになってきました。
その中で、私の経験不足に寄らないMLチームの状況的・構造的な問題も見えてきたため、改善活動を行っています。
この記事ではスタンバイのMLチームにおける「チーム化」について書いていきます。

# 背景
### MLチームの性質
MLという分野は属人性が高くなりやすい分野です。
しかも、スタンバイのML系の業務は多岐にわたります。　今現在MLを使っていなくても、今後ML的なアルゴリズムを適用する可能性があるような分野はMLチームで検討することも多いです。
現在は各テーマに対して担当が2人付く形で業務を進めています。

### スタンバイMLチーム特有の問題
スタンバイのMLチームでは、
- 各テーマに担当が2人ずつつけない状態
- 保守運用が特定のメンバーに偏る状態

が発生していました。

メンバーが優秀なため、課題に対しての議論はできますが、もし誰かが倒れたら引き継ぎなどはできないという危機的な状況です。

### 新メンバー受け入れの状況
さらに、
- 各テーマについてのドキュメントは存在するものの、前提知識が抜けている
- そもそもオンボーディングのやり方を忘れている
    - 特にまだエンジニア3年目という、ほぼ新卒みたいな新メンバーをサポートする体制はなくて当たり前です
    - ここは後に新メンバーが入るたびにFBをして改善傾向です

といった状況にも陥っていました。
こうなってくると、各々が各々のテーマに忙殺されて、そもそもどういうタスクがあるのかが中々見えてきませんでした。

# 目標
私のようなジュニアエンジニアが生き残っていくためには、チームメンバーとのコミュニケーションが欠かせません。
そのため、以下3つの目標を立てて、チームの運営を改善していくことに決めました。
1. MLチームの属人性を低減する
2. 保守運用などのタスクの偏りを解消する
3.  アイディアを出す議論から、その一歩先の議論へ

### 課題となる点
ところで、スタンバイでは多くのチームでスクラム開発が採用されています。特に、MLチームのお隣である検索エンジン自体を管掌しているチームでは、かなりしっかりとしたスクラム開発が行われています。
検索とMLは連携するべき部分が多いため、スクラムイベントに合同で出たりも行っています。

しかし、スクラム開発とMLチームは相性が悪いものです。

スクラム開発では、スプリント毎に成果を出すことが期待されます。しかし、MLの成果には不確実性があります。思ったほどの精度が出なかった、分析対象のデータの品質が低かった、そもそもモデルの学習や前処理自体に時間がかかるため非同期で実行可能な作業を先に実施していた…。
もちろん、「モデルの学習から推論までを実施した」ということを成果と呼ぶのであれば適用していくことは可能かもしれませんが、それはスクラム開発というフレームワークのスプリントゴールとして適切ではないでしょう。

また、業務を円滑に進めようと始めた施策に時間を取られるすぎると業務に支障をきたす可能性がありますし、ドラスティックな変更というのは反発も招きます。せっかくチームの改善をしようとしても、精神的な部分で溝ができてしまったチームは、近いうちに瓦解するのではないでしょうか。

### 改善していくためのポイント
以上から、MLチームのチーム運営を改善するためのポイントを決めました
- 全員が現状を改善すべきことだと認識していること
    - お互いが改善すべきだと認識していないとそもそも改善は進みません
- MLの業務の進み方に合う方法であること
    - 単純にお隣のチームを手本にスクラムイベントをやってもスタンバイのMLの業務方針に合わなければ空回りしてしまいます
- 保守運用など、定常的なタスクに焦点を当てること
    - 新メンバーが入って行きやすいのは個人的には保守運用を見ることだと思っています。　

定常で走っている集計結果の分析や、モデルパイプラインのメンテナンス、各システムのEOL対応などを通して実際に今解決すべき課題が見えてきます。　
…もしかしたらシニアでスーパーなエンジニアとかだったらそんなこともないのかもしれないですが、少なくとも私はそうです

# 実際に実施していること
- retrospectiveの新設
    - 頻度：月1回
    - 内容：前回から今回までの間にあったことをKPTで振り返ります
- mini retroの追加
    - 頻度：週1回
    - リファインメントのアジェンダです。その週にあったことを書き溜める時間です。
    喫緊の課題があった場合はここで解決するか、別途ミーティングを立てて早期解決を目指します。 

他にも、テーマがない場合は流会したり早仕舞いしていた相談系のミーティングの活用をしています。

# 実行したことによる効果・変化
正直なところを言うと、チーム全体で大きく変わっているような実感はまだありません。私は今もメンバーの報告を聞きながら、「後で資料を読もう…」と考えていますし、アイディア出し以上の議論ができていると言うつもりもありません。
また、新メンバーが業務に入っていく早さは個人差があります。簡単に比較できるものでもありません。（比較されると私の遅さが際立ちます）

しかし、チームメンバーは積極的に参加してくれています。
今後は保守運用タスクの偏りなど、なるべく定量的な指標を探して施策の効果を確認していこうと考えています。
PC再起動後にDockerのMySQLテーブルデータが消えた問題

#### **はじめに**
Dockerを使ったMySQLのローカル開発環境を構築中に、PC再起動後にMySQLのテーブルデータが消えてしまう問題が発生しました。同時に、データベースの復旧を試みた際にエラーが発生し、ダンプファイルの再インポートも失敗しました。本記事では、発生した事象、対応内容、考えられる原因をまとめます。

---

#### **発生した事象**
1. **PCを再起動してDocker Desktopを再起動**  
   - Dockerコンテナ（MySQL、アプリケーション、phpMyAdmin）は正常に起動。
   - しかし、MySQLデータベースに接続した際、**テーブルデータが空**になっていることを確認。
   - phpMyAdminでデータベースのテーブルを参照しようとすると、以下のエラーが発生:
     ```
     Tablespace is missing for table `hogehoge`.`hugahuga_table`.
     ```
2. **ダンプファイルの再インポートを試みた際のエラー**  
   - ダンプファイルのインポートを試みたところ、以下のエラーが発生しインポートできず:
     ```
     Tablespace '`hogehoge`.`hugahuga_table`' exists.
     ```
   - 既存のテーブルスペースが原因でインポートが拒否される状態。

3. **Docker Desktop上で停止→再起動の場合(問題解決後に実施)**  
   - Docker Desktop上でコンテナを停止してから再起動した場合は、データが正常に残存しており、問題は発生しなかった。

---

#### **対応内容**
1. **コンテナを削除して環境を再構築**  
   以下の手順でDocker環境をリセット。
   ```bash
   docker rm hogehoge_db
   docker system prune -a --volumes
   docker-compose build
   docker-compose up -d
   ```
2. **ダンプファイルを再インポート**  
   - 新たに構築した環境にダンプファイルをインポートし直し、動作確認を実施。
   - エラーは発生せず、正常に動作。

---

#### **考えられる原因**
1. **データ永続化の設定ミス**  
   - `docker-compose.yml`では以下の設定をしていた:
     ```yaml
     volumes:
       - ./db:/var/lib/mysql
     ```
   - しかし、ホスト側の`db`ディレクトリにMySQLの必要なデータファイルが完全に保存されていない可能性。

2. **MySQLデータの破損**  
   - PCの強制終了や不適切なシャットダウンが原因で、MySQLのテーブルスペースが破損した可能性。

---

#### **検討事項**
1. **データ永続化の設定を見直す**  
   - データ永続化にホスト側ディレクトリ（`./db`）を使う場合、必要なファイルが正しく保存されているか確認。
   - Dockerボリュームを使用することで、ホスト側のファイルシステム依存を減らす選択肢も検討。

2. **MySQLのバックアップ体制を強化**  
   - 定期的に`mysqldump`でデータベースのバックアップを取得する。

3. **PC再起動とコンテナ停止→起動の違いを検証**  
   - 再現テストを行い、どの条件でデータが失われるのかを特定。

4. **Docker Desktopのログ確認**  
   - 再起動時のエラーが記録されていないか、Docker Desktopのログを確認。

5. **起動手順により起きる可能性** 
    * mysqlを起動(当然サーバーにはログイン出来ないが)してからDockerDesktopを起動すると、高確率で同様の不具合になることが分かった。順番が違っても、Dockerを起動したら使えると思うのだが…違うのだろうか

---

#### **まとめ**
今回の問題は、Dockerを利用する際のデータ永続化設定や再起動時の処理に起因する可能性があります。原因の特定には至っていませんが、再発防止のための設定見直しや検証を進める必要があります。

--- 

#### **参考**
- [Dockerの公式ドキュメント](https://docs.docker.com/)
- [Qiita記事: 「Dockerデータ永続化」](https://qiita.com/naiveprince0507/items/6c2ebda455e5aa1b39e9)  
- [Qiita記事: 「DockerでのMySQLデータ永続化」](https://qiita.com/Toyo_m/items/95a2543c07dc5b126208)
NewRelicデータエクスプローラーとは

## はじめに
NewRelicでリソースやログ監視をしているとNRQLを使ってデータを可視化する（グラフとかテーブルとかで）
その際にNRQLのクエリ記述方法がわからない際にデータエクスプローラーを活用すると探してるデータを簡単に特定し、取得、可視化できる。

## データエクスプローラー
データエクスプローラーを使用すると、New Relic データベース (NRDB) に保存されているすべてのデータにすばやく直感的にアクセスでき、属性を使用してクエリのファセットを選択し、必要な値までフィルタリングすることができる。

### 検索できるデータ型
- メトリクスデータ型（Metric streamsでデータを取ってきてる場合）
- イベントのデータ型（API Pollingでデータを取ってきてる場合）

```
Metric streamsとAPI PollingはAWS上のメトリクスデータをNewRelicに取り込む方法
Metric streams：AWS CloudWatchがNewRelicに対してデータを送る。CloudWatchのメトリクスストリーム機能を利用
API Polling：NewRelicがAWSのデータを取得しに行く
```
AWSからNewRelicからの違いがある。

### 画面例（公式情報から抜粋）
![data-explorer.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3172936/e1eba6a1-98f1-925d-5e22-1f61232be16a.gif)

## 公式情報
よくある質問とトラブルシューティング AWS Integration
https://newrelic.com/jp/blog/how-to-relic/faq-newrelic-aws-integration

データエクスプローラーの概要
https://docs.newrelic.com/jp/docs/query-your-data/explore-query-data/query-builder/introduction-new-data-explorer/
【NewRelic】API Keysに保存されているKeyのValue値を取得する方法(NerdGraph)

# 概要
GUIから参照できなくなった、KeyのValue値を簡単に取得する方法をご紹介します。

# 目次
 <toc>

 - [概要](#概要)
 - [背景](#背景)
 - [KeyのValue値取得方法](KeyのValue値取得方法)

# 背景
- 2024年の7月下旬にnewrelic社よりライセンスキーの管理方法が変更される通知があり、
今までGUIでKeyのValue値が参照できたが、2024/09/25以降は参照できなくなります。とのこと
 
- メール件名
[Product Notice] Action Required: Change to user and license keys
- 内容要約
New Relic から、ユーザーとライセンスキーの管理方法が変更されることが通知されました。
2024年9月25日以降、UIからAPIキーをコピーする機能が削除されます。
既存のAPIキーは、NerdGraph APIを使用して取得することができます。
2024年9月25日までに、既存のAPIキーをNew Relic外の安全な場所に保存する必要があります。
新しいAPIキーを生成する場合は、ページを離れる前にキーをNew Relic外の安全な場所にコピーする必要があります。
 
# KeyのValue値取得方法

- NardGraph APIから参照する

1.newrelic管理画面の左ペインよりAppsを選択
　※Appsが表示されていない方は三点リーダーより選択ください。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924351/5cb253c4-2dfb-4f63-0e44-87f908d6d881.png)


2.NerdGraph API Explorerを開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924351/887973bf-5152-47c7-1754-8d6e9c57a2cb.png)


3.NerdGraph API Explorerを利用するための自身のユーザーkey(NRAK-******)を入力しsubmit
　※自身のユーザーKeyが分からない場合は、「API Keys」より「Create Key」にてKeyを作成します。
 　「Key type」について「User」を選択すること！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924351/1f6b5ddf-51ae-3f11-1115-d275aeb81965.png)


4.無事NerdGraph API Explorerが利用できるようになったら、以下サンプルコード入力し、加工します。
　※加工が完了したら、右上の実行ボタンを押すと、右側に結果が表示されます。

## USER KEY
```
query USERKEY {
  actor {
    account(id: 【参照したいキーのアカウントID】) {
      id
    }
    apiAccess {
      key(
        id: "【参照したいキーのKEYID】"
        keyType: USER
      ) {
        name
        ... on ApiAccessUserKey {
          name
          key
        }
      }
    }
  }
}
```

## INGEST KEY
```
query INGESTKEY {
  actor {
    account(id: 【参照したいキーのアカウントID】) {
      id
    }
    apiAccess {
      key(
        id: "【参照したいキーのKEYID】"
        keyType: INGEST
      ) {
        name
        ... on ApiAccessIngestKey {
          id
          name
          key
        }
      }
    }
  }
}
```

以上、ご参考になれば幸いです。
ROSA HCPで使用するOIDCプロバイダーに関する備忘録

# 1. はじめに
ROSA HCPのクラスターを作成する際、CLIでOIDCプロバイダーを設定する手順があります。
OIDCプロバイダーとはどういう働きをするもので、ROSA HCPクラスター作成時にOIDCプロバイダーの設定がなぜ必要なのか、初学者である筆者は理解するのに苦労したため、備忘録もかねて当記事を執筆しました。

※この記事の内容は2024年12月現在の情報であり、下記の製品リリースに基づいています。
Red Hat OpenShift Service on AWS with Hosted Control Planes v4.14.37

# 2. 目次
- [1. はじめに](#1-はじめに)
- [2. 目次](#2-目次)
- [3. ROSA HCPにOIDCプロバイダーの設定がなぜ必要なのか](#3-rosa-hcpにoidcプロバイダーの設定がなぜ必要なのか)
  - [3.1. 前提としてROSA HCPはSTSによる一時認証方式を使用する](#31-前提としてrosa-hcpはstsによる一時認証方式を使用する)
  - [3.2. OIDCプロバイダーの働き](#32-oidcプロバイダーの働き)
- [4. OIDCプロバイダーとAWS STSがどのように連携して認証を行うか](#4-oidcプロバイダーとaws-stsがどのように連携して認証を行うか)
- [5. まとめ](#5-まとめ)

# 3. ROSA HCPにOIDCプロバイダーの設定がなぜ必要なのか
  ## 3.1. 前提としてROSA HCPはSTSによる一時認証方式を使用する 
- ROSA HCPでは、AWSアカウント内のリソースを管理する権限をRed Hat SREチームや、クラスター内のコンポーネント（Operator）に付与するために、AWS STS（Security Token Service）を使用します。
- こちらについては、わたしが書いた以下の記事も参考にしていただければと思います。
  [ROSA HCPのAccountロールとOperatorロールについて](https://qiita.com/23kasu_/private/785840716b1b021ea760)
- STSは、IAMロールの信頼ポリシーの内容を検証し、信頼ポリシーに記載されたプリンシパルからのリクエストの場合のみ、認証情報を発行します。
- しかし、信頼ポリシーのプリンシパルとして指定できるのはIAMエンティティのみであり、クラスター内のOperatorは信頼ポリシー内で直接指定することができません。例えば「このPodだけがS3にアクセスできる」という設定は、STSだけでは実現できません。
- そこで活躍するのが、OIDCプロバイダーです。OIDCプロバイダーを導入することで、クラスター内のOperatorがIAMロールを引き受けられるようになります。
  ## 3.2. OIDCプロバイダーの働き
- OIDCプロバイダーは**認証にJWT（JSON Web Token）を使用**します。
  - このJWTには、「誰がどのロールを引き受ける権限を持っているか」という情報が含まれています。この際の「誰が」の部分には、OperetorないしはPodも含めることができます。
- IAMロールの信頼ポリシーに、「このOIDCプロバイダーから発行されたトークンを信頼する」という設定を含めれば、OIDCとSTSが連携してIAMエンティティ以外のコンポーネントにも一時的な認証情報を付与することができます。
  
# 4. OIDCプロバイダーとAWS STSがどのように連携して認証を行うか
- 本項目では、OIDCプロバイダーとAWS STSが連携して、一時的なセキュリティ認証情報をROSAクラスター内のOperetarに与える際のざっくりとしたワークフローを説明します。
  ※ROSA公式ドキュメント内の[ROSA with HCP ワークフロー](https://docs.redhat.com/ja/documentation/red_hat_openshift_service_on_aws/4/html-single/about/index#hcp-sts-process)に記載の内容をもとにまとめております。より正確な情報を知りたい方はこちらを参照してください。
  1. **事前準備として、認証情報を与えたいOperetorに必要な権限が定義されたIAMロールをこちらで割り当てます。**
     - ROSA HCPクラスターの場合、クラスター作成時の手順としてCLIで「オペレーターロール」作成用のコマンドを実行する必要があります。コマンドを実行すると自動で8つのIAMロールが作成され、AWS管理ポリシーがアタッチされます。
     - この「オペレーターロール」こそが、Operetorに必要な権限が定義されたIAMロールです。
  2. **Operatorが、クラスター内で設定されたOIDCプロバイダーに対して、JWT（JSON Web Token）を送信します。**
     - OIDCプロバイダーは、このトークンが正しいものであるかを確認します。
  3. **OIDCプロバイダーがIAMロールを確認します。**
     - トークンに含まれる情報が、IAMロールの信頼ポリシーに記載された条件と一致するかをOIDCプロバイダーが確認します。
  4. **OIDCがトークンを承認すると、STSが一時的な認証情報を払い出します。**
     - OIDCプロバイダーはトークンを承認すると、その情報を元にsts:AssumeRoleWithWebIdentity APIを呼び出します。
     - AWS STSは、そのIAMロールに基づいて、一時的な認証情報（アクセスキー、シークレットキー、セッショントークン）を生成し、Operatorに返します。
  5. **OperatorがAWSリソースにアクセスします。**
     - Operatorは、受け取った一時的な認証情報を使用して、AWSリソースにアクセスし、必要なタスクを実行します。
     - 認証情報は有効期限（通常1時間以内）が切れると無効になります。必要になったら、再度トークンを取得します。
- より簡単にまとめると、以下のような流れになります。
  1. Operator → OIDCプロバイダーにJWTを送信。
  2. OIDCプロバイダー → トークンを検証し、ロールの使用を承認。
  3. OIDCプロバイダー → STSにリクエストを送信（AssumeRoleWithWebIdentity）。
  4. STS → 一時的な認証情報を生成してOperatorに提供。
  5. Operator → 認証情報を使ってAWSリソースにアクセス。
# 5. まとめ
OIDCプロバイダーは、クラスター内のOperatorとAWS IAMロールを安全に連携させるために必要な仕組みです。STSだけではAWSのIAMエンティティ以外のコンポーネント対して権限を付与することが困難であるため、OIDCプロバイダーを使用します。
[C#]簡単な条件であれば三項演算子を使おう！

## 三項演算子を使っていますか？
みなさんは三項演算子という文法をつかっていますか？
自分は簡単な分岐処理とかは結構これにしてしまいます。
~~あとは過去にif文禁止とかいうとんでもない謎プロジェクトにいたこともありその機会に覚えたりしました~~
## 使い方
仮にif文で簡単な分岐をまずは書いてみましょう。
簡単にペットが「ねこ」であれば大好きフラグを立てるという簡単なプログラムを書いてみましょう！

```C#
string PetText;//ペットのテキスト
bool isLike;//大好きフラグ

if(PetText=="ねこ")
｛
    isLike=true;
｝
else
{
    isLike=false;
｝
```

仮にif文で書くとこうなりますね。
では参考演算子で書いてみましょう！
```C#
string PetText;//ペットのテキスト
bool isLike;//大好きフラグ

//参考演算子での条件
isLike=PetText=="ねこ"?true:false;
```
そうです、この１行だけで済みます！
式の内訳としてはこうなってます。
> (条件)?(trueで返す値):(flaseで返す値)

簡単な条件であれば三項演算子であれば１行で済むのでとてもオススメします！
デメリットとしてはパッと見だとんif文よりも見づらくて可読性が悪いかもです。
とはいえ簡単な条件でif文ネストするよりかは断然いいとおもうのでぜひ活用してみてください。

おわり
【新卒必見】日報はこう書いとけ！！！

[グレンジ Advent Calendar 2024](https://qiita.com/advent-calendar/2024/grenge) 7日目担当のmikuri8です。
普段はゲームクライアントエンジニアとしてUnityでUIを実装しています。また最近は新卒育成やマネジメントにも興味があり勉強を進めているところです。

今回は賛否両論ありそうな**日報**について書きたいと思います。報告よりも**振り返り**として扱えるような日報の書き方を知ることで**自走**していく手助けになればと思います。

# はじめに
日報が持つ役割は様々だと思いますが、今回は書いた本人の振り返りという部分にフォーカスします。振り返りを行い、課題点を見つけ、解決策を考えることで明日の自分をより良くしていく作業です。
本記事は日報の書き方や意義に悩んでいたり、見積もりや作業時間などの時間管理を見直したい方（もしくはその上司の方）を対象として書いてみます。
まだ勉強し始めの身でもある現時点での考えなので一意見として見てもらえれば幸いです。

# ふつうパターン
よく見る感じの日報は下記のようなものになると思います。
```
【今日やったこと】
◯◯ミーティング
作業△△△
作業□□□
【次回やること】
作業□□□続き
作業◇◇◇
【感想】
思ったより時間がかかって大変だった
だけど学びがあったので良かった
```
# おすすめパターン
次に振り返りがしやすいと考える日報のフォーマットです。
```
【今日やったこと】
◯◯ミーティング XX時間
作業△△△ YY時間
作業□□□ ZZ時間
【次回やること】
作業□□□続き XX時間
作業◇◇◇ YY時間
【振り返り】
[Probrem]作業□□□の途中でSlackで質問待ちをしていたため作業が止まり見積もり時間を過ぎてしまった。
→[Try]直接コミュニケーションを取る
→[Try]質問待ちの間次の作業の準備を行う
```
なんと変更点はほとんどないんですが、重要なのは**作業時間を書く**ことです。

# なにがいいの？
まず自分が日報を自身の振り返りに使用すべきと考えるのは、単なる報告に使うだけなら**大抵別のツールで管理されてるので日報じゃなくてもいい**という点があるからです（タスク管理やガントチャートの類）。
そのため、どうせなら振り返りに使えるようにして、ついでに**自分の頭で考える筋肉を鍛える**トレーニング化しちゃって自省のコツを掴めるようなデイリーのツールにすることで日報が便利なものになっていくのでは？と思っています。

### 作業時間の記載
提案したフォーマットでは作業時間の記載が増えました。これには**時間管理についての意識**を持つという目的があります。
学生時代には時間の制約がほぼないため、満足行くまで時間をかけてしまうことができてしまうものですが、対して社会人（会社員）は限られた時間の中でパフォーマンスを発揮していくことが求められます。
ここの違いで躓いてしまう若手は割と見かけるので、時間に関する振り返りを精度高く行っていくことが助けになるケースは多いんじゃないかなという仮説です。

### 時間の振り返り
そこで作業時間を書くことで**見積もり通りなのか遅れたのかがひとめで判断でき、その原因と解決策を探る方向に動く**ことができるのではないかと考えました。また、日報として書き出すことで時間配分や優先順の違いに気づかれやすくなりフィードバックをもらうことも可能です。翌日の作業の見積もりを行えることもポイントで、どの作業にどのくらい時間がかかりそうか考える解像度を上げていくこともできると思っています。

### 内容の振り返り
そして最後に振り返り部分ですが、ここには問題点と解決策を考えて書きます。この時重要なのは**間違っていてもいいのでまずは考えて書くこと**と、**Tryを必ず実行するものとして書くこと**です。
一点目については前述の通り考える筋肉を鍛える作業です。日報として書くので間違っていればこちらもフィードバックをもらいやすいのではないでしょうか。
ニ点目については、振り返りにおける解決策を明日にでも実行するものとして考える意識です。小さくてもいいので少し解決できれば成長。「振り返り≠感想」を意識し、タスクを洗い出す感覚で考えたほうがいいのかなと思います。

### 学び
【学び】項目を付け加えるのもいいかなと思います。学びをあらためて文字にすることで記憶に残したり実はまだ理解が足りない部分が明らかになったり学び自体の振り返りとして使用できます。

### 書くタイミング
**日報はその日の作業が終了した時点で書きましょう**。**次の日の朝に書くのは避けたほうがいいと考えてます**。寝てしまったら前日の記憶があやふやになることは多いですよね（特に飲み会後）。

# 最後に
今回は時間管理の振り返りができそうな日報の書き方を紹介してみました。日報に関しては様々意見があると思いますがフォーマットが決められていない場合は一つの手法として本記事を参考にしてもらえれば幸いです。
最後まで読んでいただきありがとうございました！
元QAが新卒開発者に伝えたい「品質とバグ」３つの心得

## はじめに
「品質が良いものを作る」ということは、世の開発者全員、永遠の課題です。
品質に対する心得というものは無限にありますが、今回は、
何十年も悩んでいる諸先輩方と肩を並べつつ、同等の課題を背負わなければならない新卒の方々へ向けて。
そして、今後長く開発者人生を送る上で重要であろう心得を絞ってお伝えします。
いろんな道標のうちの１つになることを願います。

## スタートに重要な心得は３つ
新卒開発者に送る心得は、以下の３つです。
1. 「バグがない」は「品質が良い」ではない
2. ミスやバグを出しても凹まなくていい
3. バグが見つかることは、品質が向上する喜ばしいこと

### 1.「バグがない」は「品質が良い」ではない
「品質が良いものを作ろう」と考えた時、
まず「バグをなくす」ことをひたすらに目指そうとしていませんか？

確かにバグが少ないことは「品質が良い」と言える一因ではあります。
ですが「品質が良い」という判断基準は様々あり、バグはそのうちの１つでしかありません。

そして「バグをなくす」ことは、実は非常に不毛なことです。
実は、**バグが０になることは決してありません。**
どれくらいありえないかと言えば、QAの基礎中の基礎で教わるレベルです。

ですので「バグをなくす」ことに固執したり躍起になったりしなくて大丈夫です。
そして、「バグをなくす」こと以外の「品質が良い」とは何かも、いつか考えてみてください。

### 2.バグやミスを出しても凹まなくていい
これもQAの基礎中の基礎の話ですが、すべての前提として、
**「人は必ずミスをする」** としています。

どんなにすごい先輩であっても、スーパーマンのようなリーダーであっても、
必ずミスをすることがあり、バグを起こすケースはあります。
完璧超人はこの世に存在しません。
そして皆「自分が絶対正しいことはなく、ミスをすることがある」と考えているでしょう。

だから「開発組織」という複数人の集いの中で、
「レビュー」や「テスト」や「QA確認」など、
あらゆる手段でミスやバグを「世に出さないよう」対策をしています。
自動化やAIを利用してミスを減らそうとしています。

なので皆さんは、自分がミスをしたりバグを出すことを恥だと思ったり、めちゃくちゃ凹まなくてよいのです。
ミスは隠さなくてよいのです。それくらい当然だ、と大手を振ってください。
やるべきことは、ミスを防ぐ対策に全力で乗っかり、みんなに見つけてもらうことです。

年次を重ねるごとに、自然とミスが少なくなり、自分で気付けることが増えてきます。
今、焦ることはありません。

### 3.バグが見つかることは、品質が向上する喜ばしいこと
レビューでの指摘やテストでのバグ報告を受けると、
自分の悪い点を攻められているようであったり、
仕事を否定されているような感じがして、
前向きな気持ちになるのが難しいと思います。
ですが、これらはすべて「より品質を良くするため」の行動です。

「品質が良くなった」という定義は非常に難しいです。
「品質を良くする」確実な行動はほとんどありません。
新機能を出したからといって必ず良くなるものではないです。
その数少ない「ほぼ必ず品質が良くなる行動」が「バグを直す」ことです。

バグを見つけたり報告されたら **「お、品質絶対上がるじゃんラッキー」** と思いましょう。

## まとめ
心得を全部まとめて言えば、

**どんなすごい人でもみんなミスったりバグを作るから、自分一人の力でバグを０にしようと気負わなくていい。
みんなで品質が良いものを作ろうとしているから、みんなを頼ろう。**

ってことです。

これからの長い長い開発人生に幸多からんことを願います。
GitHub上でRevertできなくなったPRをRevertしたい

## Revertしようとしたら怒られた

![ScreenShot 2024-12-06 11.44.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/a9bb1ae6-bab5-cb14-86f4-67a8279d9f5c.png)

![ScreenShot 2024-12-06 11.43.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/1fada396-6ca1-5c5f-172e-5ab279c8ecb3.png)

```
Sorry, this pull request couldn’t be reverted automatically. It may have already been reverted, or the content may have changed since it was merged.
```

自動でリバートしようとしたけど、マージ後にファイル変更が入ったからリバートできないっぽいです。

```
$ git fetch
$ git switch -c revert-branch origin/main
$ git revert -m 1 a12345678

# ... コンフリクト解消する

$ git add .
$ git revert --continue
```

ローカルでrevertしてコンフリクト解消すればokでした。

## 補足: -m オプション

今回はマージコミットをリバートしてるので -m オプションが必要です。

```
$ git revert a12345678
error: commit a12345678 is a merge but no -m option was given.
fatal: revert failed
```

-m オプションを指定しないとエラーになります。

```
$ git revert -m
    -m, --[no-]mainline <parent-number>
                          select mainline parent
                          merge strategy
                          option for merge strategy
                          GPG sign commit
```

使い方はこうです。

```
$ git revert -m <親番号> <コミットID>
```

## 補足: parent-number(親番号)

```
$ git show a12345678
commit a12345678128a51bbb7ee8800f0a83558adbb83e
Merge: b12312312 c45645645
Author: ucan-lab
Date:   Fri Dec 6 14:11:52 2024 +0900
```

この例だと 左のコミット(b12312312)が親番号1で右のコミット(c45645645)が親番号2です。

親番号1(マージ先ブランチ)を基準にします。
これを指定するとマージ元ブランチの変更のみを取り消す形になります。
親番号2を基準にするとマージ先ブランチの変更を取り消す形になるので通常は使用しないはずです。
SpyMemcachedのバックオフ戦略 (Backoff Strategy)について

## SpyMemcachedが指数バックオフ戦略を採用しているかの調査
#### はじめに
Memcachedは、高速なキャッシュ機能を提供するために広く利用されています。そのクライアントライブラリとして人気のあるSpyMemcachedも、効率的な接続管理が重要です。本記事では、SpyMemcachedが再接続時に指数バックオフ（Exponential Backoff）戦略を採用しているかどうかを、最新のソースコードを基に調査しました。

#### ソースコードの確認
SpyMemcachedの最新ソースコードは、GitHubリポジトリで公開されています。以下に、再接続戦略に関連する主要な部分を抜粋し、分析を行いました。

1. 接続最大遅延時間の設定
再接続試行時の最大遅延時間を設定する部分。

```
public class ConnectionFactoryBuilder {
    // 省略

    /**
     * Set the maximum reconnect delay.
     */
    public ConnectionFactoryBuilder setMaxReconnectDelay(long to) {
        assert to > 0 : "Reconnect delay must be a positive number";
        maxReconnectDelay = to;
        return this;
    }

    // 省略
}
```
2.最大遅延時間の単位
maxReconnectDelayは秒単位で設定され、ミリ秒に変換されています。

```
public class MemcachedConnection extends SpyThread {
    // 省略

    maxDelay = TimeUnit.SECONDS.toMillis(f.getMaxReconnectDelay());

    // 省略
}
```

3 .再接続試行間隔の計算式
再接続試行間隔は、ノードに対する再接続試行の回数を取得した後、2の再接続試行回数乗を計算し、ミリ秒に変換して最小値を取ることで決定されます。

```
public class MemcachedConnection extends SpyThread {
    // 省略

    protected void queueReconnect(final MemcachedNode node) {
        // 省略
        long delay = (long) Math.min(maxDelay, Math.pow(2, node.getReconnectCount()) * 1000);
        // 省略
    }

    // 省略
}
```
### 調査結果
上記のソースコードから、SpyMemcachedが指数バックオフ戦略を採用していることが確認できました。具体的には、再接続試行間隔が以下のように計算されています：

再接続試行回数が0回目の場合:

delay = min(maxDelay, 2^0 * 1000) = min(maxDelay, 1000ms)
初回の再接続試行間隔は1秒です。
再接続試行回数が1回目の場合:

delay = min(maxDelay, 2^1 * 1000) = min(maxDelay, 2000ms)
2回目の再接続試行間隔は2秒です。
再接続試行回数が2回目以降の場合:

delay = min(maxDelay, 2^2 * 1000) = min(maxDelay, 4000ms)
しかし、maxReconnectDelayが2秒（2000ms）に設定されているため、3回目以降の再接続試行間隔も2秒に固定されます。
### 結論
SpyMemcachedは、再接続試行時に指数バックオフ戦略を採用しています。ただし、maxReconnectDelayが2秒に設定されているため、再接続試行間隔は初回が1秒、2回目以降は2秒に固定されます。この設定により、再接続試行が過度に頻繁に行われることを防ぎ、システムへの負荷を軽減しています。

### 参考資料
https://github.com/couchbase/spymemcached/blob/master/src/main/java/net/spy/memcached/MemcachedConnection.java
自分用メモ：Outlook VBAでメッセージ（.msg）ファイル保存するマクロ

:::note info
いちいち所定のフォルダを開いてメールをコピペするのも面倒だったので作りました。
本当はBoxまで繋げたかったけど、パワーオートメイト組むのもめんどくさいのでいつか…。
:::
:::note warn
「参考にしたサイト」に内包されているので本記事は読まなくていいと思います。
:::

### Outlook VBAでメッセージ（.msg）ファイル保存するマクロを組む

以下、参考にしたサイト
[001 Outlook VBA メール本体と添付資料を一発保存マクロ シンプル版 - くのへスタジオ (kunohe.tech)](https://kunohe.tech/outlook-vba/300/)

```vb:ThisOutlookSession.vba

Sub メール保存() '参考ページ→ https://kunohe.tech/outlook-vba/300/

  Dim objIns As Outlook.Inspector
  Dim objItem As Object
  'Dim strName As String
  Dim subjectName As String
  Dim strPath As String
  Dim objAttachment As Object
  'Dim objFSO As Object
  Dim strFile As String
 
  Set objIns = Application.ActiveInspector
  Set objItem = objIns.CurrentItem
  
  strPath = "C:\Users\お好きなパス\" 'ファイルを保存したい場所のアドレス。末尾に「\」を付けること
  subjectName = objItem.Subject
  
  If subjectName Like "*:*" Then 'メール件名に「:」があれば「_」に置換
    subjectName = Replace(subjectName, ":", "_")
  End If
  
  objItem.SaveAs strPath & subjectName & ".msg"

  With objItem
    For Each objAttachment In .Attachments
        strFile = strPath & strName & "\" & objAttachment
        objAttachment.SaveAsFile strFile
    Next objAttachment
  End With

End Sub
```
法改正対応ヘルプの白羽の矢が立ってモブプログラミングで解決した話

# はじめに
:::note info
この記事は[LITALICO Engineers Advent Calendar 2024](https://qiita.com/advent-calendar/2024/litalico) シリーズ2の12日目の記事です
:::
LITALICOでエンジニアをしている@takmonです。
今回は、2024年度の障害福祉法改正に伴い、システム改修のヘルプを行った経験についてお話しします。
まずは、私の直近の経歴を簡単にご紹介します。

## 直近の簡単な経歴
| 年月 | 所属 | 内容 |
| -- | -- | -- |
| 〜2018年6月 | 某介護福祉業界のメガベンチャー | 介護事業所にて利用者に提供したサービスをもとに国保連（国）へ給付費を請求するSaaSの開発・保守を担当。法改正を2度経験。 |
| 2018年7月〜2022年3月 | LITALICO | 障害児福祉教室にて、利用者に提供したサービスをもとに国保連（国）へ給付費を請求するSaaSの新規開発および保守運用を担当。法改正を1度経験。 |
| 2022年4月〜 | LITALICO | 障害福祉・児童福祉業界で働く人向けの求人サイトの開発・保守・運用を担当 |

介護業界と障害福祉業界の違いはありますが、これまでに法改正を合計3回（2015年、2018年、2021年）経験しました。

# 法改正ヘルプで担当したSaaSについて
弊社は2020年12月に福祉ソフト株式会社をグループ会社化しました。
福祉ソフトが扱っていたSaaSは、現在もLITALICOで「[かんたん請求ソフト](https://campaign.fukushisoft.co.jp/seikyu)」として提供しています。
このソフトを簡単に説明すると、指定のExcelフォーマットに入力されたデータをアップロードするだけで、国保連に請求するためのCSVファイルを作成できるものです。

# そもそも法改正って何？
法改正は主に3年に1度のサイクルで行われます。
内容はその時々によって異なりますが、職員の報酬アップや新しいサービスの追加などが挙げられます。

## 法改正対応は具体的に何するの？
SaaSの役割は、国保連に請求するためのCSVを作成することです。
国保連側で定義されているCSVのインターフェース仕様は、法改正によって変更されることがあり、それに対応するためのシステム改修が必要になります。
（例：[2024年度法改正時のインターフェース仕様書](https://www.mhlw.go.jp/content/12200000/2024040900003.pdf)）
また、施設や事業所が利用者に提供したサービスごとに点数（単位数と呼びます）が定められています。
一般の方に馴染みのあるもので例えるなら、病院で診察を受けた際に受け取る診療報酬明細書に「初診〇〇点」といったものを見たことあるのではないでしょうか？
それと同じように、介護・福祉業界でも、例えば「初回サービス提供時は〇〇単位」といった形で単位数が決まっています。
法改正により、この単位数が変更されることがあり（ほぼ毎回変更があります）、その際にはマスターデータの更新が必要です。
なお、3年ごとの法改正以外でも、消費税増税などが発生した場合にはデータの変更が必要になる場合もあります。
（例：[2024年度法改正時のサービスコード表（サービスの内容と単位数の一覧）の一部](https://www.mhlw.go.jp/content/12200000/0424008.pdf)）

# 白羽の矢が立った背景
私の直近の経歴にも記載していますが、現在は求人サイトの開発部署に所属しており、通常は法改正対応には関与していません。
そのため、法改正に関する情報のインプットは全くしていない状況でした。

法改正の内容も踏まえ、社内体制の見直しが発生した結果「かんたん請求ソフトの法改正」へ急な戦力強化が必要となりました
法改正対応にはドメイン知識が不可欠であり、業務委託の方を採用して対応するには時間が不足していました。
そのため、社内でドメイン知識のある人材を探した結果、これまで法改正を3度経験した私が指名されることになりました。

# 開発チーム体制
開発チームは以下の3名で構成されました。

- 私
- 業務委託エンジニア 2名（うち1名は私より先にプロジェクトに参画）

# 何をしたのか
かんたん請求ソフトは約30種類のサービスに対応していますが、それらすべてを改修するのは非常に大変です。
弊社には、一部のサービス種類に関する請求計算のみを行う別のシステムがあり、そちらも法改正対応を行うため、それと連携することで対応すべきサービス種類を減らす方針になりました。
ので、実際の法改正対応に先んじてそちらのシステムと連携する改修を行い、それが終わってから連携していないサービス種類に対して法改正対応を行いました。

# どうやったのか
- **私**: ドメイン知識はあるが、かんたん請求ソフトのシステムについては未経験。
- **業務委託A**: システムを把握しているが、ドメイン知識が乏しい。
- **業務委託B**: 参画タイミングが私とほぼ同じで、システム知識もドメイン知識も未習得。

といった状況だったので、それぞれ何かしらのインプットが足りていない状態でした。
なので、モブプログラミングを行いそれぞれの知識を共有しつつ進める方針にしました。
なお、私はこれまでもモブプログラミングで業務を行ってきたことがあるのでノウハウは持ってました。

# 結果は？
モブプログラミングを導入することでレビューのリードタイムがほぼゼロになったので、結果的に開発スピードは上がったと思います。
モブプログラミングはメンバー全員で同時に作業するため並列作業に比べ工数がかかる一方、レビューフィードバックや手戻りを減らせる利点があります。
今回のようにインプットすべき内容が多く、難易度が高い場合には非常に有効な手法でした。

ただし、すべての場面で有効というわけではないため、状況に応じて開発手法を柔軟に選択することが重要だと感じました。

# おわりに
今回の対応を通じて、ドメイン知識を持つエンジニアの重要性を再認識しました。
現在、弊社では絶賛エンジニア募集中です。
もしこの記事を読んだ方で障害福祉に知見がある方がいらっしゃれば、ぜひLITALICOで一緒に仕事しませんか？

明日は [@k_orita](https://qiita.com/k_orita) さんの記事になります。
お楽しみに！