OmniAICreator/Qiita-1.07M huggingface dataset:
【Kubernetes運用効率化】sternで複数Podのログをリアルタイム監視する方法まとめ

## sternとは？Kubernetesログを一括表示するCLIツール

`stern`は、複数Podのログを**ラベルや名前パターンで絞って、リアルタイムに tail**できるCLIツールです。  
本記事では、`stern`のインストール方法と活用事例を実務目線でまとめます。

`kubectl logs`ではなく`stern`を使う利点は主に以下のような点です。
- 複数Podのログを一括表示可能
- 各コンテナのログを時系列で表示できる
- --selectorオプションで特定のラベルが付与されたPodのログのみ表示可能
- --excludeオプションでログを正規表現で指定可能

#  :books: 想定読者

- `kubectl logs` が面倒に感じている方
- 複数Podのログを横断的に確認したいKubernetesユーザー
- DevOps・SREを目指す方

# :signal_strength:sternのインストール方法

macOS環境の方は方法①で、Linux環境の方は方法②でインストール
方法①: Homebrew(macOS向け)
```bash
brew install stern
```

方法②: バイナリダウンロード(Linux向け)
```bash
# 最新バージョンを確認（例: v1.29.0）
$ VERSION=$(curl -s https://api.github.com/repos/stern/stern/releases/latest | grep tag_name | cut -d '"' -f 4)
$ echo $VERSION  #←バージョンが表示されるか確認

# ダウンロードしてインストール（Linux amd64 の場合）
$ curl -LO https://github.com/stern/stern/releases/download/${VERSION}/stern_${VERSION#v}_linux_amd64.tar.gz

# 解凍して /usr/local/bin に移動
$ tar -xzf stern_${VERSION#v}_linux_amd64.tar.gz
$ sudo mv stern /usr/local/bin/
```
🔍 確認：インストールが完了したかどうか以下のコマンドで確認
```bash
$ stern --version
```
他にもインストール方法は存在するので以下のサイトを参考にしてください
https://github.com/stern/stern 

# :thinking: 基本的な使い方
Pod名の一部でログを確認(myapp-・・・Podが複数存在するとします)
```bash
$ stern myapp
```
 Namespaceを指定(my-namespaceにあるmyappのログを取得)
```bash
$ stern -n my-namespace myapp
```

ラベルセレクタでPodを指定(ラベルappの値がmyappのPodのログを取得)
 ```bash
$ stern -l app=myapp
```

タイムスタンプ付きで見る
```bash
$ stern -t myapp
```

# 🎯 活用例：現場で役立つ3パターン
✅ CI/CD後にログを即チェック
```bash
$ stern -n dev -l app=myapi
```

✅ 複数Podの振る舞いをまとめて確認
```bash
$ stern .  # 全Pod対象（便利だが注意）
```

✅ container指定（複数コンテナPod対応）
```bash
$ stern mypod --container frontend
```
🔧 よく使うオプション
| コマンド                           | 説明                 |
| ------------------------------ | ------------------ |
| `stern .`                      | すべてのPodのログを tail   |
| `stern -n my-namespace app`    | 特定のNamespaceでログを見る |
| `stern -l app=myapp`           | ラベルで対象Podを絞る       |
| `stern -t`                     | タイムスタンプを表示         |
| `stern -o json`                | JSON形式で出力          |
| `stern --container container1` | 特定コンテナのみ表示（複数ある場合） |


# :rolling_eyes: kubectl logsとの違い
| 機能       | kubectl logs | stern   |
| -------- | ------------ | ------- |
| リアルタイム表示 | `-f` で可      | デフォルトで可 |
| 複数Pod対応  | スクリプト要       | 対応済み    |
| カラーログ表示  | ×            | ✅       |
| ラベル選択    | ×            | ✅       |

# :pencil: まとめ
`stern` は Kubernetes ログ確認の効率を劇的に改善

複数Pod、複数コンテナ、ラベルベースで柔軟にtailできる

kubectl logs で消耗していたら即導入すべき

## 📚 公式ドキュメント・参考リンク

- [stern GitHub リポジトリ](https://github.com/stern/stern)
- [kubectl logs公式ドキュメント](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#logs)

# 👨‍💻 著者について
インフラ・セキュリティ・DevOpsを中心に活動中の大学3年(執筆時)

KubernetesやCI/CD（GitLab×GKE）を軸にポートフォリオを構築中

よければフォローお願いします 🙌
3段階のチェックボックス

# はじめに
WEBシステムで、3段階のチェックボックスを作ろうと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779420/39b371a7-c776-4d34-b7a7-8b6568ff4e73.png)

# 調べてみる
どこを調べても、javascriptでindeterminateをtrueにすれば良いという情報ばかりでした。

```html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <input type="checkbox" />
    <input type="checkbox" checked/>
    <input type="checkbox" id="chkIndeterminate"/>
</body>
<script type="text/javascript">
    document.getElementById('chkIndeterminate').indeterminate = true;
</script>
</html>
```

CSSだけで何とかしたい…

# CSSだけで作ってみる

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="qEdJwvB" data-pen-title="Untitled" data-user="cjlsrdxi-the-builder" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/cjlsrdxi-the-builder/pen/qEdJwvB">
  Untitled</a> by masayasu_t (<a href="https://codepen.io/cjlsrdxi-the-builder">@cjlsrdxi-the-builder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

チェックボックスに見えますが、正体はラジオボタンです。

非表示にしている要素を表示すると、このようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779420/796056f7-c3a6-4959-91e5-51cc32df95c6.png)

チェックなし状態と左、チェックあり状態と真ん中、3ステータス状態と右のラジオボタンがリンクしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779420/ca26722a-b040-4ab4-8a6c-c354cb0e7853.png)

そして、右のラジオボタンにチェックが入っているときは、チェックなし状態を表示（チェックあり状態と3ステータス状態は非表示）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779420/8835f940-82d7-422f-9084-92b0482f43fb.png)

左のラジオボタンにチェックが入っているときは、チェックあり状態を表示（チェックなし状態と3ステータス状態は非表示）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779420/2b189f2b-5253-40d8-a6d9-a7d3143ed038.png)

真ん中のラジオボタンにチェックが入っているときは、3ステータス状態を表示（チェックなし状態とチェックあり状態は非表示）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779420/9e957df9-186d-4d1c-9b73-5273517f3a39.png)


# おわりに
このやり方を用いると4段階以上のチェックボックス？が作れます。
デザインのバリエーションを増やすために作ってみましたが、使い勝手は微妙です
LLMモデル APIキー従量課金について

これからclaude のAPIキーを取得しようと思ったのですが、従量課金制になってます。つまり使った分だけが課金されるのです。でも計算方法が分からない。実際「**いくらかかるのか？**」を先に知っておきたくて調べてみました。

## 料金はトークンで課金される
LLMのAPIは、**トークン**という単位で課金されるようです。
そういえば昔、ニューヨークに行ったときに、地下鉄の改札を通るのに専用コインが必要だったんですが、そのコインも **“Token”** と呼ばれてました。500円玉くらいの大きさで、真ん中に穴が開いてました。**Token** は「お金の代わりに使うもの」という意味なんでしょうかね。
ちなみに、地下鉄の改札周辺にはホームレスっぽい人がいたりして、“Token please, Token please…” とか、 “Cigarette please…” とかよく声をかけられました。（すみません、話がそれました。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3742888/291c44e3-eb01-4a67-906f-ca3e586cc3ff.png)


出展　https://docs.anthropic.com/en/docs/about-claude/pricing

## トークンとは？

大規模言語モデル（LLM）でいう「トークン」とは、**テキストを処理する最小単位**のこと。文字をトークン化するようですが、「文字 ＝ トークン」ではなくて、「文字のまとまり = トークン」という感じで、少し分かりずらい。。

## 1トークンは何文字？

**英語の場合、約4文字で1トークン** と書かれていました。（記事参考）
1文字 ≒ 0.25トークンとも言えます。
これは、１トークンが４文字という意味ではなくて、大量の英語テキストを分析した結果、だいたい **4文字/トークン**になるっていうことみたいです。

文字数から単純にトークン数を計算するのではないのですが、とりあえず、私は **１文字0.25トークン**で計算してみることにします。

参考→ As a general rule, one token is roughly four characters in English.

▶参考 https://yomotherboard.com/anthropic-claude-ai-token-calculator/?utm_source=chatgpt.com

（例）`console.log("Hello World!")` →　27文字 ÷ 4 =  **約 7 トークン**（簡易計算）

　　※これは英語テキストの場合です。

🔍 ちなみに、LLMモデルがどのようにコードをトークン化しているのか、それは**トークナイザー**というツールを使っているようです。このトークナイザーにはいくつか種類があって、LLMモデルによって異なるようですが、今回私が知りたいのは、課金される概算金額なので、ここは飛ばすことにします。

## 💰 主要LLM API価格 （1Mトークンあたり）

（2025年6月調べ）1Mトークン=100万トークン
| **モデル** | **入力トークン** | **出力トークン** |
| --- | --- | --- |
| **GPT‑4 Turbo** | $10 | $30 |
| **GPT‑3.5 Turbo** | $0.50 | $1.50 |
| **Claude 4 Sonnet** | $3 | $15 |
| **Claude 4 Opus** | $15 | $75 |

結構差ができました。
※あくまで個人調べです。最新は公式を確認してください。

## 💡 シュミレーション
例：**Claude 4 Sonnet API** を使って1ファイル（3,000文字と仮定）を出力した場合、トークン数と料金はどうなる？

### :page_facing_up:１ファイル出力した場合：

**トークン数:** 3,000文字 ÷ 4 = **750トークン**
**コスト:** 750トークン ÷ 1,000,000(単位1M) × $15 = **$0.01125**（1ドル150円で換算で**約1.69円**）

###  :calendar_spiral:一ヶ月利用していくらくらいになるか

1ファイル3,000文字として計算

| **月間処理数** | **総トークン** | **総コスト** |
| --- | --- | --- |
| 1ファイル | 750 | $0.01125（1.69円） |
| 10ファイル | 7,500 | $0.1125（17円） |
| 100ファイル | 75,000 | $1.125（169円） |
| 500ファイル | 375,000 | $5.625（844円） |

### 💭シュミレーション結果について一言:
シュミレーションは、ファイル出力のみで計算してます。実際は「Input Tokens」「5m cache writes」「1h cache writes」「Cache Hits & Refreshes」でもカウントされるし、もっとトークンが消費されます。
とりあえず、Claude 4 Sonnet API を使って、1ファイル3000文字が出力された場合、1.69円くらいだと覚えておくことにします。

## **まとめ**
これからNext.jsでWebアプリを開発する予定だったのですが、安く済みそうな気もするし、そうでない気もします。結論、使ってみないと分からないかもです。。予算的には1,000円以内に収めたいです。実際使ってみたら違うかったなどあれば、また追記します。読んでいただき、ありがとうございました！

追記-
始めて書きました。間違ったことは書けないので、少しビビりながら書きました。もし誤りや気になる点があれば、ぜひコメントで教えてください！


🔗 参考リンク
▶ claude公式料金ページ→ https://docs.anthropic.com/en/docs/about-claude/pricing
▶ Claude Token Calculator→ https://yomotherboard.com/anthropic-claude-ai-token-calculator/?utm_source=chatgpt.com
▶ Zennの参考記事→ https://zenn.dev/akifqc/articles/8f5b65040ff57b

（2025年6月時点）
Rails + DockerでCSSが効かない真っ白画面の本当の原因とリカバリー術！

## 😱 問題：Railsアプリが真っ白！CSSが読み込まれない！

Docker + Railsでアプリを起動したら、**画面が真っ白！CSSが効かない！**  
`application.bootstrap.css` を指定しても効果なし…。

---

## 🔥 原因：Dockerコンテナの `public/assets` がホスト側で上書きされてる！

```yaml
volumes:
  - .:/app
```
この設定のままだと、ホストの空っぽな ./public/assets が、
コンテナ内の /app/public/assets を上書きしちゃうんです！

💥 結果的に：
	•	rails assets:precompile で作られたCSSが見えない状態に！
	•	CSSが読み込めず、画面が真っ白に…

⸻

✅ 解決策：public/assets のボリュームマウントを避ける！
```yaml
volumes:
  - .:/app
  - /app/public/assets  # ← これを追加！
```
こうすることで、ホストの空フォルダで上書きされるのを防げます！

⸻

🚀 リカバリーステップ
```
docker compose down
docker compose build --no-cache
docker compose up -d
docker compose exec web bundle exec rails assets:precompile
docker compose restart web
```

⸻

🎉 結果：CSSが適用され、正常な画面表示に！

Bootstrapデザインもバッチリ復活✨
もう、真っ白地獄からはサヨナラです！

⸻

おわりに

Rails + Docker 環境でCSSが反映されないときは、ボリューム設定を疑うのがコツ！
Rails初心者さんでも安心して進められるように、この記事が参考になれば嬉しいですっ！
闘魂AWS: AWS SimuLearnでクラウド＆生成AIを体験！講師目線でも感心した完成度の高さ

# はじめに

AWS公式の学習プラットフォーム「[AWS Skill Builder](https://skillbuilder.aws/)」で、無料で提供されているSimuLearnコンテンツを2つ体験してみました。

* **AWS SimuLearn: クラウド、はじめの一歩**（主にEC2を扱います）
* **AWS SimuLearn: 生成 AI を使い始める**（SageMaker AIを体験できます）

どちらも「仮想シナリオ」の中でステップバイステップで操作しながら学んでいく形式で、**学習用にAWSコンソールまで提供される**という親切設計。AWSアカウントすら不要で学べます。

私は普段、学生にAWSやプログラミングを教えることがあります。その目線から見ても「講義の設計として非常に優れている」と感じました。

✅ Educator(教育者)としてのCredlyバッジを披露しておきます。
私のバッジはこちら：
👉 [AWS Academy Educator](https://www.credly.com/badges/7e112b42-c527-4a32-b5c4-30ccd6c3f22d/public_url)


# SimuLearnの構成：冷たく突き放すDIYが最高

どちらのコースも、以下のような4段階構成になっています：

0. **背景ストーリー（小話）**
   　登場人物やビジネスの課題が紹介されます。意外と大事。

1. **学習ビデオ**
   　仕組みの解説。基礎的ですが丁寧です。

2. **実践チュートリアル**
   　用意された演習用のAWSコンソールを使って、丁寧にステップバイステップで進みます。

3. **DIY(Do it yourself: お主、やってみろ)**
   　「さっきのやつ、自力でやってみよう！」というパート。急に冷たくなったようでいて、実は大切な最後のステップです。

この流れがとても良くできていて、**一方向的なビデオ学習ではなく、「ちゃんと手を動かして理解を定着させる」設計**になっていました。

---

# クラウドはじめの一歩：復習にも最適

「AWS SimuLearn: クラウド、はじめの一歩」は、EC2を中心に**クラウドの基本的な考え方**が学べるコースです。

すでにAWSを少し触ったことがある方にとっては「知ってる内容も多い」と思うかもしれませんが、それだけに**復習として非常に良い構成**だと感じました。

特に以下の点が印象に残りました：

* **グローバルインフラストラクチャ**の話が丁寧
* なぜ今クラウドなのか、というビジネス背景の解説
* クラウドプラクティショナーやソリューションアーキテクトの入口として最適

「AWSって何ができるの？」と聞かれたら、このコースを紹介しておけば間違いありません。

---

# 生成AIを使い始める：SageMakerを触れるワクワク体験

「AWS SimuLearn: 生成 AI を使い始める」では、**名前だけ聞いたことのあるSageMaker**を実際に使ってみることができます。

* モデルのエンドポイントを立てる
* Jupyter Notebookを開く
* Promptを書き込む（Zero-shot / One-shot / Few-shot）

という流れで、「**自分で生成AIモデルをデプロイして、叩くってこういうことか！**」と感覚がつかめる体験ができます。
しかも、**無料で、アカウント不要で**。これ、めちゃくちゃ大きいです。

---

# 講師目線でも高評価：教材設計の良さにうなる

私は大学や専門学校でもAWSやプログラミングを教えることがあります。SimuLearnの構成は非常に参考になります。

* 導入でシナリオ（Why）を示す
* 動画で理論（What）を伝える
* 実践で手を動かす（How）
* 最後にDIYで自力で再現する（定着）

という構成は、**まさに理想的な教材の流れ**です。今後の講義にも取り入れていきたいと感じました。

---

# まとめ：全人類にオススメできる無料体験

AWS Skill BuilderのSimuLearnシリーズは、**AWS未経験者にも、経験者の復習にも、そして教育者にも**強くオススメできる内容です。この記事では2つのトレーニングのみを紹介しました。他にも魅力的なコンテンツが多数用意されています。

![スクリーンショット 2025-06-22 0.17.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/85c3b28e-5a40-4bcb-8a5d-6fa9314b6b41.png)


AWSアカウント不要でここまでできるのか……という感動すらあります。
AWSに少しでも興味のある方、**とりあえずSimuLearnで「一歩目」を踏み出してみてはいかがでしょうか？**

> 迷ったら、まず触ってみる。行動が未来を変える第一歩です。

この道を行けばどうなるものか
危ぶむなかれ
危ぶめば道はなし
踏み出せば
その一足が道となり
その一足が道となる
迷わず行けよ
行けば分かるさ

:::note
🧠 本記事が誰かの学びの背中を押すきっかけになれば、筆者としてこれ以上の喜びはありません。
:::
ビルドとは

「ビルド（Build）」とは、ソフトウェア開発において、**ソースコードから実行可能なプログラムや配布可能なパッケージを作成するまでの一連の工程全体**を指す言葉です。

先ほど説明した「コンパイル」は、この「ビルド」という大きなプロセスの一部に含まれます。

### ビルドに含まれる主な工程

ビルドは、単にソースコードを機械語に変換するだけでなく、以下のような様々な工程を統合したものです。

1.  **ソースコードの作成**: プログラマがプログラミング言語でコードを記述します。
2.  **静的解析（Static Analysis）**: ソースコードの文法や潜在的なエラー、コーディング規約への準拠などを、実行せずに解析します。
3.  **前処理（Preprocessing）**: コンパイルの前に、ヘッダファイルの読み込みやマクロの展開などを行います。
4.  **コンパイル（Compile）**: ソースコードをオブジェクトコード（機械語に近い中間コード）に変換します。
5.  **リンク（Link）**: コンパイルによって生成された複数のオブジェクトファイルや、外部のライブラリファイルなどを結合して、最終的な実行可能ファイルを作成します。
6.  **パッケージング（Packaging）**: 実行可能ファイルだけでなく、プログラムの動作に必要なリソースファイル（画像、音声、設定ファイルなど）やドキュメントなどをまとめて、配布可能な形式（インストーラ、アーカイブファイルなど）に圧縮・整理します。
7.  **テスト（Test）**: 作成されたプログラムが期待通りに動作するかを検証します。ビルドプロセスに自動テストが組み込まれることも多いです。

### なぜ「ビルド」という概念が必要か

* **複雑なソフトウェアの統合**: 実際のソフトウェアは、単一のファイルで構成されることは稀です。複数のソースファイル、外部ライブラリ、リソースファイルなどが連携して動作します。ビルドは、これらを「組み立てて（Build）」一つの動くソフトウェアにするプロセスです。
* **開発の効率化**: 手作業でこれらの工程を行うのは非常に手間がかかり、ミスも発生しやすいため、多くの場合「ビルドツール」（例: Make, Maven, Gradle, webpackなど）が用いられ、ビルドプロセスが自動化されます。
* **再現性の確保**: 常に同じ手順でソフトウェアを生成することで、異なる環境や時間でも同じバージョンのソフトウェアを作成できる再現性を確保します。
* **バージョン管理との連携**: ソースコードの変更を検知して自動的にビルドを実行する「継続的インテグレーション（CI）」などの仕組みと連携することで、ソフトウェアの品質を継続的に保ちやすくなります。

### まとめ

「コンパイル」はソースコードを機械語に変換する**個別の作業**を指しますが、「ビルド」はソフトウェアを構成する全ての要素を統合し、**実行可能な状態にするまでの一連の工程全体**を指します。つまり、コンパイルはビルドの一部として行われる、より広い概念がビルドであると理解すると良いでしょう。
ブリッジとは

## React Nativeの「ブリッジ」とは：JavaScriptとネイティブの通訳者

React Nativeにおける「**ブリッジ（Bridge）**」とは、**JavaScript（TypeScript）で書かれたアプリケーションのロジックと、iOS（Objective-C/Swift）やAndroid（Java/Kotlin）といったネイティブコードの間で、データのやり取りや関数呼び出しを可能にするための通信メカニズム**のことです。

React Nativeアプリの大部分はJavaScriptで動作しますが、デバイスのカメラやGPS、プッシュ通知といったOS固有の機能は、JavaScriptから直接アクセスできません。ブリッジは、このJavaScriptの世界とネイティブの世界をつなぐ「通訳者」のような役割を果たします。

具体的には、JavaScript側からのネイティブ機能の呼び出しやデータの要求を、ブリッジが受け取り、それをネイティブコードが理解できる形式に変換して伝達します。ネイティブ側で処理が完了すると、その結果を再びブリッジが受け取り、JavaScriptが理解できる形式に変換して返します。この双方向の通信を仲介することで、React NativeアプリはJavaScriptの柔軟性と、ネイティブ機能のパフォーマンスやOSとの深い連携を両立させているのです。
Railsコントローラで使う `protected` と `private` の違いを解説！

## ✨ はじめに

Ruby on Railsのコントローラで `protected` や `private` を使う機会、よくありますよね！  
でも「どっちを使えばいいの？🤔」と迷っちゃうことも。

本記事では、それぞれの違いと、**Rails開発におけるベストな使い分け**を、初心者でもわかりやすく解説します！

---

## ✅ `protected` とは？

```ruby
protected
```
  • 同じクラス or 継承先クラスの 別のインスタンス からも呼べる
  • before_action などの フィルター・コールバックでよく使われる

📌 例
```ruby
class ApplicationController < ActionController::Base
  before_action :authenticate_user!

  protected

  def authenticate_user!
    redirect_to new_user_session_path unless user_signed_in?
  end
end
```


✅ private とは？

private

  • 同一インスタンス内のみ で呼び出し可能
  • 他クラス・他インスタンスからはアクセス不可

📌 例
```ruby
class WelcomeController < ApplicationController
  def hello
    greet_user
  end

  private

  def greet_user
    puts "Hello, user!"
  end
end
```

🆚 違いをざっくり比較！

比較項目	protected	private
アクセス範囲	継承元・子クラス間の別インスタンスもOK	同一インスタンス内のみ
Rails用途	before_action に最適	内部ヘルパーや補助メソッドに最適

✅ まとめ
	•	コールバック・フィルター ⇒ protected
	•	補助的な内部処理 ⇒ private

適切に使い分けて、キレイで読みやすいRailsアプリにしましょう！
ネイティブモジュールとは

## ネイティブモジュールとは：React NativeアプリとOS機能をつなぐ架け橋

「**ネイティブモジュール**」とは、React Nativeのようなクロスプラットフォームフレームワークにおいて、**JavaScript（TypeScript）のコードから、各デバイスのOS（iOSやAndroid）固有の機能やハードウェアにアクセスするために、ネイティブ言語（iOSならObjective-C/Swift、AndroidならJava/Kotlin）で実装された機能の単位**を指します。

React Nativeアプリは、大部分をJavaScriptで記述しますが、カメラ、GPS、プッシュ通知、高性能なグラフィック処理、または既存のネイティブSDKの組み込みといった特定の機能は、JavaScriptだけでは直接利用できません。

ネイティブモジュールは、JavaScriptとネイティブコードの間に「**ブリッジ**」と呼ばれる通信路を設け、JavaScriptからのリクエストをネイティブコードに伝え、ネイティブコードがOSのAPIを実行した結果をJavaScriptに返す役割を担います。これにより、React Native開発者は、JavaScriptの柔軟性を保ちながら、各プラットフォームの持つ強力な機能や最高のパフォーマンスをアプリに取り入れることが可能になります。
ネイティブコードとは

## ネイティブコードとは：コンピュータが直接理解する唯一の言葉

「**ネイティブコード**」とは、特定のコンピュータのCPU（中央処理装置）が**直接理解し、実行できる形式のプログラムコード**のことです。別名「機械語（マシン語）」とも呼ばれます。

プログラミング言語（C, C++, Swift, Javaなど）で書かれたソースコードは、そのままではコンピュータには理解できません。そこで「コンパイル」という過程を経て、CPUが直接実行可能な0と1の羅列に変換されます。この変換された最終形式がネイティブコードです。

ネイティブコードは、**特定のプラットフォーム（CPUアーキテクチャとオペレーティングシステムの組み合わせ）に依存する**という特徴があります。例えば、WindowsのIntel CPU向けにコンパイルされたネイティブコードは、macOSのARM CPUでは直接実行できません。このプラットフォーム依存性があるからこそ、中間変換なしにCPUが直接実行できるため、**極めて高いパフォーマンス**を発揮します。ゲームやグラフィック処理、OSの中核部分など、速度と効率が最優先される場面で不可欠な存在です。
Svelte 5 の時代に v4 をインストールする

## あらすじ

Svelteの環境構築したろ！
せや、ついでに[Svelte DevTools](https://chromewebstore.google.com/detail/svelte-devtools/kfidecgcdjjfpeckbblhmfkhmlgecoff)も使えば開発効率爆上がりやしそっちもいれたろ！

![No Svelte app detected](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736050/d8bebd3b-525e-47d9-8f7c-a05304a3356f.png)

> Use Svelte version ^4.0.0?

意訳：DevTools は Svelte v4 しか対応しとらんけど大丈夫か？

そして古いSvelteの環境構築の旅が始まるのだった―――。

### 【参考】DevTools の Svelte 5 への対応状況

https://github.com/sveltejs/svelte-devtools/issues/193


## Svelte 4 のインストール方法

古いインストーラーである[create-svelte](https://www.npmjs.com/package/create-svelte?activeTab=readme)を利用する。
最新のv7は[sv](https://www.npmjs.com/package/sv)を使えというエラーが出て使えないので、１つ古いv6を利用する。

```bash:npm
npm create svelte@^6 my-app
```

```bash:pnpm
pnpm create svelte@^6 my-app
```

あとは画面通りにインストールすればOK。

## 結果

無事 Svelte 4 のインストールが完了し、Svelte DevToolsも使えるようになったぜ！
![Svelte v4](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736050/6a5d3cc3-6b88-4de7-9413-77cad01b46f0.png)

## 参考

- https://v4.svelte.dev/
- [create-svelte - npm](https://www.npmjs.com/package/create-svelte?activeTab=readme)
【Python】NumPyのデータ型

整数のデフォルトはint64で、小数のデフォルトはfloat64である。

ただし、OS、Python、NumPyのバージョンなど、環境によって変わることがあります。

dtype属性でデータ型を確認できる。

dtype属性は以下のように使います。

arr = np.array([1])
arr.dtype
▶︎ dtype('int64')


属性のため、「dtype(arr)」ではなく「arr.dtype」と記述します。

なお、要素の型ではなくオブジェクトの型を確認するtype関数は、関数のため「type(arr) ▶︎ numpy.ndarray」と記述します。type関数はNumPyの関数ではなく、Python標準の関数です。

astypeメソッドで以下のように記述して、データ型を変更できます。

arr = np.array([1])
arr.astype(np.float64)
▶︎ array([1.])

int32やint64の数字部分は、確保するメモリ量を表している。

正しい説明です。

int64などの数字部分は確保するメモリ量を表しており、以下の範囲の数値を要素に格納できます。

int16 → 2バイト（-32768〜32767）

int32 → 4バイト（-2147483648〜2147483647）

int64 → 8バイト（-9223372036854775808〜9223372036854775807）


Numpyの主なデータ型は以下があります。

bool（論理型）

int16、int32、int64（整数）

float16、float32、float64（浮動小数点数）

datetime64、timedelta64（日時）


datetime64は、「date = np.array('2015-07-04', dtype=np.datetime64)」のように記述して作成します。
ABC411をPythonで（A～D）

ユニークビジョンプログラミングコンテスト2025 夏（AtCoder Beginner Contest 411）の解答等の速報的まとめ

https://atcoder.jp/contests/abc411



# A問題
https://atcoder.jp/contests/abc411/tasks/abc411_a

文字列の長さと数字を比較
```python:A
print("Yes" if len(input()) >= int(input()) else "No")
```


# B問題
https://atcoder.jp/contests/abc411/tasks/abc411_b

０地点からの距離を計算しておいて、差分を計算するだけにする
```python:B
n = int(input())
d = list(map(int, input().split()))

for i in range(len(d) - 1):
    d[i + 1] += d[i]

d = [0] + d

for i in range(n):
    for j in range(i + 1, n):
        print(d[j] - d[i], end=" ")
    print()
```


# C問題
https://atcoder.jp/contests/abc411/tasks/abc411_c

自身が黒か白かと左右それぞれが黒か白かで場合分けして
どうなったら組数が増減するかを考えた
```python:C
n, q = map(int, input().split())
lst = [False] * n

ans = 0
for a_i in map(lambda x:int(x) - 1, input().split()):
    is_front_black = a_i - 1 >= 0 and lst[a_i - 1]
    is_back_black = a_i + 1 < n and lst[a_i + 1]

    if lst[a_i]:
        lst[a_i] = False
        if is_front_black and is_back_black:
            ans += 1
        elif is_front_black or is_back_black:
            pass
        else:
            ans -= 1
    else:
        lst[a_i] = True
        if is_front_black and is_back_black:
            ans -= 1
        elif is_front_black or is_back_black:
            pass
        else:
            ans += 1
    print(ans)
```


# D問題
https://atcoder.jp/contests/abc411/tasks/abc411_d

クエリを逆から見てどれを参照するかを追っかけていく
```python:D
n, q = map(int, input().split())
query = [list(input().split()) for _ in range(q)]

target = "0"
ans = list()
for q_i in query[::-1]:
    if q_i[0] == "2" and q_i[1] == target:
        ans.append(q_i[2])
    elif q_i[0] == "1" and q_i[1] == target:
        target = "0"
    elif q_i[0] == "3" and target == "0":
        target = q_i[1]

print(*ans[::-1], sep="")
```
開発サーバーが起動しない...? 犯人はfileproviderdの暴走だった話

## はじめに
Mac(M2 Air)でNext.jsの個人開発をしていたところ、突如としてMacが重くなり、ターミナルすら反応しなくなる地獄に遭遇しました。
その個人開発ではモノリポ構成（Next.js, Express.js)で開発していたため、ファイルのネストが深くなってしまうことが原因かと思っていましたが、違いました。

## 💥 結論：Macのデスクトップに開発用ファイルを絶対置くな！！

### ❌ ダメな理由
実は、MacBookの「デスクトップ」フォルダは、初期設定だと自動でiCloudに同期されるようになっています。
そして、これが開発環境でトラブルを引き起こす落とし穴になっていました。

特にNext.jsなどで開発サーバーを起動していると、.next/ や .turbo/ に大量のファイルがリアルタイムで生成・変更され続けます。
これに対してiCloudの同期プロセスである fileproviderd が反応し、そのすべてをアップロードしようとしてCPUを占拠し始めるのです。

## 😨 暴走の引き金
### → 「iCloudのリアルタイム同期」 と 「Next.jsのFast Refresh開発」 が事故る
 macOSのiCloud同期は、**「対象フォルダ内のファイルが変更されるたびに即座にiCloudに反映しようとする」**　仕組みになっている。
一方Next.jsはfast refres（ホットリロード）開発によりファイルを保存するたびにリアルタイムで画面に反映されるようになっています。

その裏で .next/ や .turbo/ に中間ファイルが頻繁に書き込まれるため、これが iCloud の同期と衝突すると fileproviderd が暴走する原因になります。





## 😱 実際に発生した症状

- ターミナルのコマンドが一切効かなくなる（`git`, `npm`, `pnpm`全滅）
- Macが異常に熱くなる
- VSCodeが固まる
- 再起動しても改善されない

## 🔍 原因特定の流れ

#### 1. アクティビティモニタで `fileproviderd` のCPU使用率を確認
→ **常に80〜140%で暴走していると判明**

![2025-06-21 17.24の画像.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836510/0cee147f-c5b1-44b2-8421-19d4659ab477.jpeg)


#### 2. `fileproviderd` を調べる
→ **iCloudのファイル同期・メタ情報処理担当プロセス**を担っていると知った

#### 3. iCloudの設定を調べる
→ **デスクトップや書類フォルダがiCloudに同期されていると判明**





## 🩹 解決方法

### 💡 開発用フォルダを iCloud 管理外（Desktop以外のディレクトリ）にgit cloneせよ！！
### なぜgit clone？
おそらく、同症状が発生するとCPU稼働が`fileproviderd`に占拠されており、`mv`で開発用フォルダをicloud外に移動させることはほぼ不可能に近いと思われます。　（私もそれで試しましたが、移動処理の読み込みが長すぎて無理でした😭)

また、一旦デスクトップのファイルを**iCloud同期オフ**にすることもできまが、iCloud Drive上でしか確認ができなくなり、閲覧するにはローカルにダウンロードする必要があります。そのため、CPU稼働が`fileproviderd`に占拠されている状態では、iCloud上の開発用ファイルのダウンロードもほぼ不可能に近いです。

これらの理由から、iCloud Drive 外のディレクトリを作成し（例：~/projects ）、速やかに`git clone`を行った方が合理的だと思われます。

#### 補足：iCloud Drive の同期を解除してみる 🔓
上記でも述べたとおり、デスクトップに存在するファイルのiCloud同期をオフにすることができ、これは`fileproviderd`のCPU稼働率が下がる可能性があります。（私の場合は下がりませんでした...）
「システム設定 → Apple ID → iCloud Drive → “デスクトップと書類フォルダを同期” のチェックを外す」

## 最後に
まさかiCloudと開発環境の相性でここまで苦しむとは思ってませんでした。笑  
こうした予期せぬトラブルも乗り越えるのも成長できる経験になりますね 😏

もし、同じ症状で悩んでいる方がいましたら、ぜひ参考にしてみてください！！
Tomcat Web App with MySQL

マイクロソフト Learnサイトに掲載されている文書を読んで実行したら、どうもうまく行かないときのメモです。

URL:
https://learn.microsoft.com/en-us/azure/app-service/tutorial-java-tomcat-mysql-app

レポジトリ：https://github.com/Azure-Samples/msdocs-tomcat-mysql-sample-app
1. Run the sample
Step 2: In the GitHub fork:

Select main > starter-no-infra for the starter branch. This branch contains just the sample project and no Azure-related files or configuration.
Select Code > Create codespace on starter-no-infra. The codespace takes a few minutes to set up.

コンテナの構築時、エラー発生。Java (with SDKMAN)インストール失敗　と怒られました。
GitHubのcodespaceはサンドボックス的な環境で、 sudo apt installは通用しません。

試行錯誤の結果：

.devcontainer\devcontainer.json

 features : { の ghcr.io/devcontainers/features/java:1" : {
  に "mavenVersion" : "3.8.6"を付け加えると、エラーが解消されました。

修正前：
	"features": {
		"ghcr.io/devcontainers/features/java:1": {
			"version": "none",
			"installMaven": "true",	
			"installGradle": "false"
		},
		"ghcr.io/azure/azure-dev/azd:latest": {},
		"ghcr.io/devcontainers/features/azure-cli:1": {}
	},

修正後：
	"features": {
		"ghcr.io/devcontainers/features/java:1": {
			"version": "none",
			"installMaven": "true",
			"mavenVersion" : "3.8.6",
			"installGradle": "false"
		},
		"ghcr.io/azure/azure-dev/azd:latest": {},
		"ghcr.io/devcontainers/features/azure-cli:1": {}
	},
    
以上です。
リヤド・メトロ完全ガイド｜サウジアラビアの未来型都市交通システム

リヤド・メトロ完全ガイド｜サウジアラビアの未来型都市交通システム
https://riyadhmetro.net/
はじめに
サウジアラビアの首都リヤドは、急速な都市化と人口増加により深刻な交通渋滞の問題に直面してきました。これを解決するために登場したのが、「リヤド・メトロ（Riyadh Metro）」です。本記事では、リヤド・メトロの概要、各路線の詳細、開発の目的、そして未来の展望まで、包括的に解説します。

リヤド・メトロとは？
リヤド・メトロは、サウジアラビア政府が推進する**「サウジ・ビジョン2030」**の一環として建設された都市鉄道システムです。リヤド市内を走る全長176kmにおよぶネットワークは、6路線・85駅で構成されており、中東地域では最大級のメトロプロジェクトです。

主な特徴：
完全自動運転（ドライバーレス）

冷房完備の車両と駅施設

男女専用車両やVIP車両の導入

最先端の交通ICシステム搭載

公共バス網と連携した多モード交通

路線別の解説
ライン1（ブルーライン）
全長：38km

駅数：22

経路：オライヤー通り（Olayya St.）とバティハー通り（Batha St.）を南北に縦断

主要連結：キング・アブドゥルアジーズ通り、バスターミナルと連携

ライン2（レッドライン）
全長：25km

駅数：13

経路：キング・ファハド通りを東西に走行

重要施設：王立博物館、ビジネス地区

ライン3（オレンジライン）
全長：40.7km（最長路線）

駅数：22

経路：西リヤドから東まで横断

特徴：工業地域や住宅地をカバーし、多様な利用者を想定

ライン4（イエローライン）
全長：29km

空港アクセスに特化

リヤド国際空港と市中心部を接続

ライン5（グリーンライン）
全長：13km

経路：王立大学周辺エリアをカバー

教育・研究機関とのアクセス向上

ライン6（パープルライン）
全長：30km

経路：市北部から南部まで縦断

建設の背景と目的
サウジアラビアでは、自家用車への依存度が非常に高く、都市の拡大と共に深刻な渋滞や排出ガス問題が顕在化していました。政府は以下の目的でリヤド・メトロを計画しました：

渋滞の緩和と通勤時間の短縮

持続可能な都市インフラの整備

市民の生活の質の向上

観光・ビジネス客の利便性向上

女性の移動手段の確保（女性専用車両あり）

現在の状況と運行開始予定
2025年時点で、建設工事のほとんどが完了しており、一部の試験運行も実施されています。正式な全面開業は2025年末から2026年初頭と予想されており、段階的に路線ごとに運行が開始される見込みです。

今後の展望
リヤド・メトロは、都市交通の中核を担うだけでなく、スマートシティ開発の象徴でもあります。将来的には以下のような展開も予定されています。

周辺都市との接続（インターシティ連携）

メトロ駅を中心とした都市再開発

スマホアプリによる完全モバイル乗車券対応

AIによる運行管理の最適化

観光客・出張者向けのポイント
英語とアラビア語の案内サイン

各駅にタクシー乗り場とバス連絡ターミナル

主要ホテル・ショッピングモールへのアクセスが良好

旅行者向けの1日パスやICカード販売あり

まとめ
リヤド・メトロは、単なる交通機関にとどまらず、サウジアラビアの持続可能な未来都市づくりの重要なピースです。都市のインフラ改革、経済多角化、そして人々の生活の質の向上を目指す壮大なプロジェクトとして、今後も注目される存在となるでしょう。
【競技プログラミング】AtCoder Beginner Contest 383問題_解法イメージ

# 既存投稿一覧ページへのリンク
[一覧ページ](https://qiita.com/o_chan_t/items/fc759695acfaef8df2cc)

# 雑記
C問題はBFS問題、D問題は解法知ってるか問題なので、後回し。
2時間くらいやって、Youtube解説見て、ようやく解法が見えてきたけど、最後の詰めが試せてない。。。(2025年6月21日22時30分現在)

正確には、解法は分かるけれど、総当たり対策だから、まずTLEするだろうなぁ～ってパターン。
まぁ、ここらへんは、10問くらい類題解けばパターンが見えて来ると思うので、忘れない間に解法を記録しておきます。

# E問題解法アプローチ
https://atcoder.jp/contests/abc383/tasks/abc383_e

<iframe width="560" height="315" src="https://www.youtube.com/embed/ZnKvG7o-ljs?si=hwxIcfz3Bt4KVpkX&amp;start=6306" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## 例1（下記の入力例）
7 16
4 7 13
1 5 10
6 5 13
5 7 12
3 6 4
1 4 12
6 7 4
3 4 11
1 6 4
5 4 19
7 1 20
4 2 1
6 4 15
7 2 16
6 2 4
2 3 13
1 1 2 4 4
3 3 5 5 7

→ 解：32

まず、前述のグラフを可視化すると、下記の様になります。

![aaa58d7uITIAAXz0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530912/b9d3a055-889c-4c54-a1b8-bc64af6b6c5c.png)


で、最小パスの重みの中から、決められた範囲の最大の重みを求めろという問題なので、
先に最小パスを求めておきます。

【Step01】
ここらへんは、最小全域木やUnionFindでさんざんやった問題だし、手作業でトレース出来る問題にしているので、下記のように求めます。
蛇足ですが、手でトレース出来るようにしておくと、アルゴリズムの理解が100倍くらい早く出来ますね。

![AtK7hXhDI2Lc7wgz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530912/d1f64b22-b565-4bcf-aff0-bbb1130fe067.png)


【Step02】
残った木の中から、
Startポイント[1 1 2 4 4]
Endポイント[3 3 5 5 7]
をいい感じに組み合わせて、パスの重みが最大になるよう設定しろという問題ですね。

![aGhTJtEOdXf3H9Ak.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530912/e584406a-73b8-4a20-b964-db6298502952.png)


ノードが7つくらいであれば、目視で出来るし、目視で出来るということは、総当たりで解答を求められるはずなのですが、まぁTLEするでしょうな。

UnionFindを使えば解けるっぽいので、「理解できるまで繰り返す」の精神で何パターンか類題といて対策することにします。

なんだかんだと今週ずっとこの問題と相対していたような気がするので、また後日。解答方針さえ目処が付けば後は、繰り返しとパターン発見で乗り切れるはずっ！
Paperspaceの運用システム：概念の紹介

システム運用の知識もプログラムと同様に紹介する価値があると思っています。

## できること：
死活監視運用により、仕様上 6時間毎の切断後に再実行できる
＊３契約 の Pro Planで並行動作。 CLIによる生成AI処理を24時間動作させ続けています。 
注意：相手サーバーへの継続アクセスとなります。継続運用には、動作間隔など十分配慮すること

## 前提：
1. OCI Free tier でLlnux vmを準備 (cron および、オプションの Public keyを受け取るサーバーとして利用)　＊他社でも、local pcでも良い。
2. Python + Selenium で GUI 操作を実施する準備とスクリプトの準備。
3. 監視側：死活監視スクリプト
4. Paperspace(Cloud GPU)側：起動スクリプト
オプション：Paperspace で生成した public keyを受け取る サーバープログラムの準備(Python + Flask)

## 死活監視スクリプトの設計：cron にて、定期実行。
0. (オプション) ssh で接続できる場合は生きている。 終了
1. Python + Selenium で PaperspaceにLogin。ステータスを取得。 Runningの場合は終了。
2. 6時間経過後や空きがなく起動失敗で、起動していない場合は、起動処理を開始する。

## 起動スクリプトと、連続する生成AI実行スクリプトの設計
1. Python + Selenium によるGUI処理：paperspace にて、notebook 起動。ー＞ console起動後に、セットアッププログラム開始
(オプション)ssh tunnel：同時に ssh をインストールし、生成した public keyを vmにpost。受け取った : VMで public keyを受け取ると、 ~/.ssh/authorized_keyに追加するサーバーで受付。私はPython + Flaskで実装
2. セットアップスクリプトの末尾で、生成AI処理を開始するスクリプトの起動

ポイント：Selenium によるGUI処理中は、各ステップで、進捗まで待つWaitを追加。および、再実行のLogicを組み込んでおくこと

*Papaspaceでは、過去有用なAPIがあったが廃止されています。API操作による過度なアクセスがあったと想像しています。
算術平均（相加平均）、相乗平均、調和平均

平均には算術平均（相加平均）、相乗平均、調和平均があり、計算式は以下となります。

【算術平均】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/fbb574b2-3e41-488c-a903-b59ce263533b.png)


一般的な平均です。


【相乗平均】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/0a18134a-ca5b-4cc9-8f9d-883e5c565397.png)


データがn個あったら、n個のデータを掛け合わせて、そのn乗根を取ります。例えば「2」と「8」というデータがあった場合、「2x8=16」となり、16の2乗根を取るため「4」となります。

相乗平均は増加率や成長率の平均を求める場合などに利用します。国民の平均年収など、正規分布しないデータも、算術平均よりも相乗平均のほうが実際の感覚に近い数値を出せることがあります。


【調和平均】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/aea16039-ce3d-4c83-b98a-3a6a3363fbb8.png)


速度の平均や、電気回路の電圧を求める場合などに利用します。

例えば、10kmを時速50km/hで進んだ後、さらに10kmを時速100km/hで進んだときの平均速度を考えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/aa8f296c-65ff-485e-b121-3eeb050645b6.png)



次の図は、距離・速さ・時間を求める「きはじ」の公式です。例えば、時間を求める場合は「じ」を隠して、「距離（き） ÷ 速さ（は）」で求めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/c27b8999-874d-4640-b0fa-8f620106731f.png)




「きはじ」の公式で合計時間を求めると、「0.2 (10km ÷ 50km/h) + 0.1 (10km ÷ 100km/h) = 0.3時間」となります。

また、例題の平均速度を一般的な算術平均で求めると、「150 (50km/h + 100km/h ) ÷ 2 = 75km/h」 となります。

この「75km/h」が正しいのか確認するために、距離の合計「20km」と計算して合計時間を求めます。

平均速度75km/hで20km進んだときの時間は、「20km ÷ 75km/h = 0.26...時間」となり、先に計算した実際の所要時間「0.3時間」と一致しません。

そこで調和平均を使って平均速度を求めます。

調和平均の式に、今回の時速を入れて平均速度を求めると次の式になり、結果は「66.6...km/h」となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/abe1a4bf-1ee1-41c2-81ed-0b3db9c47e8b.png)



66.6km/hで20km進んだときの時間は「20km ÷ 66.6km/h = 0.3...時間」となり、実際の所要時間と近似します。

調和平均は、平均を求める対象が同じ数字の分子で算出された場合に利用します。今回の例題では、最初にそれぞれの速度を求めた際に、分子となる2つの距離が10kmと10kmで同じだったため、算術平均ではなく調和平均が適切でした。距離が10kmと20kmのように異なっている場合は算術平均が適しています。

機械学習の分類モデルの評価で用いるF値は、適合率と再現率の調和平均で計算します。適合率も再現率も、どちらも分子が「TP（正例と予測して実際に正例）」であるため、算術平均ではなく調和平均が適しています。F値の詳細は上級問題38で解説します。

なお、大小の関係で見ると「算術平均 ≧ 相乗平均 ≧ 調和平均」となります。
Githut Copilot coding agentを上限限界まで使ってみて、issueを任せた感想

## はじめに
Copilotの機能であるcoding agentを使ってみたく、Copilot Pro+に登録してPro+のプランの範囲で使用できるだけ使ってみました。
今回は、使ってみた際の良かったissue内容やあまり意図通りに行かなかった内容をまとめようと思います。

## Copilot coding agentとは？
まずCopilot coding agentは、githubのCopilotの機能として追加された現段階ではプレビューの機能で、
できることは、リポジトリのIssueにアサインすることでそのissueを自動的に修正し、プルリクエストまで作成してくれます。
また、プルリクエストを自動で作ってくれる機能もあります。

https://docs.github.com/ja/copilot/using-github-copilot/coding-agent

導入方法や簡単な使い方は下記にまとめましたので、使ってみたい方はこちらを参考にしてみてください

https://tkwork.tech/copilot-coding-agent-demo/

## 任せて良かった点
思い通りに修正してくれた点は、修正内容が明確で細かく指示した場合にはほとんど意図通りに修正してくれました。

例えば、下記のようにかなり細かく内容を指定して、issueを作成することでかなりの精度で修正を行なってくれました。
- 機能タイトル / Feature Title
- 解決したい課題 / Problem Statement
- 提案する解決策 / Proposed Solution
- 機能カテゴリ / Feature Category
- 技術的アプローチ / Technical Approach
- 影響するコンポーネント / Affected Components
- ユーザーストーリー / User Stories
- 受入条件 / Acceptance Criteria
- モックアップ・参考資料 / Mockups & References


また、UI/UX関連でかなり大雑把に「より使いやすく、見た目も良くすることを実現する」のような指示をすると、普通に使いやすいUI/UXになっていて、感動しました。

下記画像は全てCopilotが作成しました。私はデザインに関しては勉強不足なため、Copilotに任せた方がいいものが作れそうです。

![スクリーンショット 2025-06-21 21.51.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3367262/ca693fde-62a6-4cb2-ba9e-25a275e07769.png)


他にも、Copilotに任せるためのissueテンプレートを作成して、のようなissueもかなり細かく、バグ用や新機能用などissueの内容それぞれで作成してくれました。

## 少し微妙だった点
やはり、使用できる量が私には少なかったです。

Copilot Pro+はプレミアムリクエストが月に1500回のリクエストまで利用できます。（それ以上は課金制）

その範囲だとissueを割り当てて、プルリクエストの修正依頼などもCopilotに任せると15個くらいで私は上限になってしまいました。
やはり、任せる内容はかなり精査してリクエストを節約しないといけません。

また、意図通りにいかなかった点は、大きな機能を任せるとあまりうまく行きませんでした。

例えば、テストコードがなく少し量のあるソースに対して、１からテストコードを作成するようなタスクをお願いすると、テストコードは作成してくれますが、コンパイルエラーが発生していたり、それ修正いらないよね？というようなファイルを修正していたりしていました。

## まとめ
現時点でissueに関しては、プロトタイプはAIに任せず一旦作成しておいて、それを参考にして修正してもらう方がCopilotの作成したプルリクエストの内容も理解しやすいですし、エラーになっている部分なども修正が簡単になります。
今後は、１つずつCopilotに任せるタスクと自分でやるタスクを分けて考えたいと思います。

Copilot coding agentはかなり精度が良く、ある程度意図した通りに実装してくれます。
この機能がもっと安く使用できるよになると、本当に多くのエンジニアがコードを書かずにレビューのみをやるだけでいい未来が待っていると思います。
【MAMP】はじめてのMySQL

## はじめに
本記事では、私が初めてデーターベースを触るときに、MySQLをMAMP環境で学習した当時の環境を軽く再現していきたいと思います。

## 環境
- MacOS
- MAMP

## MAMPをインストール
以下のサイトにて、Downloadボタンを押しMAMPをダウンロードします。

https://www.mamp.info/en/mac/

## サーバー起動
MAMPを起動し、「WebStart」をクリックすると、
http://localhost:8888/MAMP が開くかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245592/841138d6-d827-446a-babe-6dfe25c02439.png)

## phpMyAdminにてテーブルを作成
ヘッダーメニューの「Tools」→「phpMyAdmin」にて、
phpmyAdmin画面に遷移すると、MySQLの管理画面が表示されます。
さらに、新規作成にて、テーブル名を入力し作成すると、空のテーブルが作成されました。
ここからさらに、画面上でテーブルにカラムを追加したり、レコードを追加したりなどができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245592/acf06dbe-57bf-4d3a-8f1d-ca35f503ec05.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245592/5ec2c6d4-e709-4de0-a4e4-210fd19e74b6.png)

## おわりに
という具合で、私はMySQLをはじめて触ったときは、phpMyAdminでテーブル作成などをしていました。
とくに初心者のうちは、複雑なSQLを使うことなく、クリック操作で作業ができるため、取っ掛かりとしては良いかもしれません。
LibreOfficeでマスク処理

個人情報が含まれたテキストファイルをマスク処理する事になったのですが、
マスクする箇所が軽く数万か所あったので、LibreOfficeでマスク処理するコード書いてみました。


```
Dim keyName As String

'■マスク処理を行う関数（ボタンに埋め込む関数⁾
Sub replace
    Dim oSheet As Object
	Dim count As Integer
	' 改行コードを除去
	call replaceKaigyo()
    oSheet = ThisComponent.Sheets(0)
	count = 0
	' マスク文字分、繰り返し
	Do While oSheet.getCellByPosition(0, count).getString() <> ""
		keyName = oSheet.getCellByPosition(0, count).getString()
		call MaskNameInSheet()
		count = count + 1
	Loop
	MsgBox("完了")
End Sub

'■改行文字を除去
Sub replaceKaigyo
    Dim oDoc As Object, oSheet As Object
    Dim oReplace As Object
    oDoc = ThisComponent
    oSheet = oDoc.Sheets(0)
	oReplace = oSheet.createReplaceDescriptor()
    oReplace.SearchString = "\n"
    oReplace.ReplaceString = ""
    oReplace.SearchRegularExpression = True
    oSheet.replaceAll(oReplace)
End Sub

'■マスク処理
Sub MaskNameInSheet()
    Dim oDoc As Object, oSheet As Object
    Dim oReplace As Object
    oDoc = ThisComponent
    oSheet = oDoc.Sheets(0)
	oReplace = oSheet.createReplaceDescriptor()
    oReplace.SearchRegularExpression = True
    oReplace.SearchString = "(^|[,\s])" + keyName + "=[^,\s]+"
    oReplace.ReplaceString = "$1" + keyName + "=***"
    oReplace.SearchRegularExpression = True
    oSheet.replaceAll(oReplace)
End Sub
```
A列に羅列した項目をマスク処理します。
（ちなみに、nameとaddressは対象、usernameとofficeaddressは対象外）
住所の中に改行コードが入っているため、初めに改行コード除去を行ってからマスク処理実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149556/0a3e014a-1f1d-4c93-84b4-9c915b7c354a.png)
マスク処理実行後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149556/f8f2f048-a2b7-4547-95c1-ae93d14ea4f9.png)
Laravelのdownload入門！

仕事で一括インポートができる機能の作成をした。

UIと一括インポート用のテンプレートがいつでもダウンロードできるように作成したんだ。

だから今回はテンプレートのダウンロードで使ったメソッドをちょいまとめとく。

---

## 1. download メソッドとは

| メソッド | 使いどころ | 書式 |
|----------|------------|--------------|
| `response()->download()` | 物理パスが分かっているファイルを強制ダウンロード | `return response()->download($path, $name, $headers);` |
| `Storage::download()`    | Storage ファサード経由でディスクから取得してダウンロード | `return Storage::download('file.jpg', $name, $headers);` |

---

## 2. 基本の使い方 ― `response()->download()`

```php
public function exportCsv()
{
    $file = public_path('exports/users.csv');
    return response()->download($file, 'users.csv');
}

```

- 第1引数: ファイルパス
- 第2引数: 保存ダイアログで表示されるファイル名（任意）
- 第3引数: 追加ヘッダー（任意）

```php
[
            'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'Content-Disposition' => 'attachment; filename="'.$filename.'"',
            'Cache-Control' => 'max-age=0',
]

```

### ヘッダー各項目の役割

| ヘッダー名 | 目的 | ポイント |
|------------|------|--------------|
| **Content-Type** | 送信するファイルの **MIME タイプ** をブラウザに伝える | - `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` は **Excel (.xlsx)** 用の正式 MIME<br>- 正しい MIME を指定しないと、ブラウザがファイル形式を誤認することがある |
| **Content-Disposition** | **ダウンロード強制** ＋ **保存時のデフォルトファイル名** を指定 | - `attachment` で「画面表示ではなく必ずダウンロード」<br>- `filename="{$filename}"` でダイアログに出る初期ファイル名を設定<br>- 日本語名は URL エンコードや RFC 5987 形式 (`filename*=UTF-8''...`) にすると文字化け防止 |
| **Cache-Control** | ブラウザやプロキシの **キャッシュ挙動** を制御 | - `max-age=0` は「キャッシュせず、毎回サーバーから取得」<br>- 個人情報や頻繁に更新されるファイルを配信するときに安全 |

**まとめ**  
- `Content-Type` で“何のファイルか”を明示。  
- `Content-Disposition` で“強制DLとファイル名”を指定。  
- `Cache-Control` で“キャッシュ有無”をコントロール。  

Cache-Controlはかなり重要。
仕様が変わった時にテンプレートをキャッシュからダウンロードさせないために0にした。

## おまけ3. Storage ファサード版 ― `Storage::download()`


```php

    public function downloadFromS3($id)
{
    $filePath = "reports/{$id}.pdf";
    return Storage::disk('s3')->download($filePath);
}

```

- local, public, s3 など 任意ディスクと組み合わせられる

↑こんな使い方もあるみたい。
だけど今回はこの方法は使っていません。
【エラー対応】GitHub Actions × Firebase デプロイエラー「Failed to get Firebase project.」

# はじめに
GitHub Actionsを使用してFirebaseにデプロイを実行したところ、エラーが出て、解決に苦戦したので記事にまとめました。

# 問題
Firebaseにホスティングしようとした際、以下のエラーが発生しました。
```
Error: Failed to get Firebase project. Please make sure the project exists and your account has permission to access it.
```


![スクリーンショット 2025-06-21 13.47.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675924/a79edf5d-7a5b-4207-a65a-9627d4e40335.png)

##  問題のコード
```
     - name: Deploy to Firebase Hosting
        uses: joinflux/firebase-tools@v9.16.0
        with:
          args: deploy --project=digital-business-card --only hosting #ここで指定しているプロジェクトIDが誤っている
        env:
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
```

## 根本原因
FirebaseプロジェクトのIDは、プロジェクト作成時に自動生成される一意の識別子です。
プロジェクト名とプロジェクトIDは異なる場合があるため、必ずFirebaseコンソールで正しいプロジェクトIDを確認する必要がありました。

# 解決方法
Firebaseコンソールで確認した正しいプロジェクトIDに書き換えることで、エラーは解消されました。

``` diff
- args: deploy --project=digital-business-card --only hosting
+ args: deploy --project=digital-business-card-9b15f --only hosting
```



## FirebaseプロジェクトIDの確認方法
1. [Firebaseコンソール](https://console.firebase.google.com/)を開く
2. デプロイしたいプロジェクトを選択する  
3. 左側メニューの歯車アイコン →「プロジェクトの設定」をクリック
4. 「全般」タブの「マイアプリ」セクションで「プロジェクトID」を確認


# おわりに
今回のエラーは、FirebaseとGitHub Actionsの認証や設定に原因があると思い込んでしまい、
実際には単純なプロジェクトIDの記述ミスだったことに気づくのに時間がかかりました。
同様のエラーに遭遇した際は、まずプロジェクトIDが正しいかを確認することをお勧めします。


# 参考
https://firebase.google.com/docs/projects/learn-more?hl=ja

https://firebase.google.com/docs/hosting/github-integration?hl=ja

https://github.com/joinflux/firebase-tools

https://github.com/marketplace/actions/deploy-to-firebase-hosting
【Flask編】Pythonで簡単Webアプリを立ち上げてみた｜Nginxとの連携準備【第2回】

## はじめに

前回の記事では、Flask + Nginx を使った自宅Webサーバの構成概要と、実際に公開しているページの全体像を紹介しました。

今回はシリーズ第2回として、**Flaskを使ったWebアプリの最小構成を作成し、ローカル環境で動作確認を行うところまで**を解説します。

FlaskはPython製の軽量なWebフレームワークで、手軽にWebアプリを構築できるのが特徴です。  

> 補足：このシリーズは自分の学習記録・ポートフォリオとしての公開を兼ねており、段階的に構築手順をまとめています。
前回の第1回の記事は[こちら](https://qiita.com/Termnix-IT/items/c9c2712bab1fceac55ad)

## Flaskの導入手順

まずはPython環境を用意し、Flaskをインストールします。  
今回はシンプルにグローバル環境でインストールしていますが、プロジェクトごとに仮想環境（venv）を使うのもおすすめです。

### Flaskのインストール

```bash
pip3 install flask
※ Python version：3.10.12 の場合
```

## 最小構成のFlask

Flaskのインストールが完了したら、早速最小構成のアプリを作成して動作確認してみます。

まずは以下のような `app.py` ファイルを作成します。

```python
from flask import Flask

# インスタンスの生成
app = Flask(__name__)

# ルートURL（/）にアクセスしたときに呼び出される関数を定義
@app.route('/')
def home():
    return "Welcome to Qiita!"

if __name__ == '__main__':
    app.run(debug=True, host="0.0.0.0", port=5000)

# debug=true デバッグモードを有効化にする設定
# サーバー起動している時にapp.pyやhtmlファイルの変更をしたときに自動的にロードされる
# 開発環境ではtrue、実環境ではセキュリティの理由でflaseに変更する

# host="0.0.0.0" 外部からアクセス可能にする設定
# 0.0.0.0はすべてのNIC(ネットワークインターフェス)で待ち受ける
# ローカル環境のみ接続可能にしたい場合は"localhost"に変更
# 今回はNginxからアクセスさせる仕組みのため、0.0.0.0に設定

# port=5000 Flaskが待ち受けるポート番号の設定
# 後のNginxとの連携でリバースプロキシ先となるため、ポート番号をメモしておく
```

`app.py` が用意出来れば準備は完了です。

## ローカルでの動作確認
`app.py` の準備が出来たら、以下のコマンドでFlaskアプリを起動してみます。
起動に関してはVScodeやCursorの様なプログラミングに特化しているエディタであれば、ファイルを右クリック「ターミナルで実行」で簡単に実行できます。

```bash
python3 app.py
# ※起動できない場合はパスを指定してみる。
# 例:python3 ./app.py
```

起動すると以下のログが表示されます。

```bash
 * Serving Flask app 'app'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://192.168.5.5:5000
Press CTRL+C to quit
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 594-652-10
```

この状態で、Webブラウザを開いて `http://localhost:5000` にアクセスすると、以下の画面が表示されるはずです。
※画像では `http://127.0.0.1:5000` と入力していますが、同じ意味なので説明は割愛

Welcome to Qiita!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092000/65460fc1-3108-445e-8eb3-51c18060a40f.png)

:::note warn
注意点
- host="0.0.0.0" にしているため、同一LAN内の他のPCやスマホから http://[サーバのIPアドレス]:5000 でもアクセス可能です。
- ファイアウォール（UFWなど）でポート5000がブロックされていると、外部からのアクセスはできません（今回はローカル確認が目的のため問題ありません）。
- debug=True の場合、コードを編集するたびに自動で再起動されます（開発中は便利ですが、本番環境では必ず False にしてください）。
:::

## まとめ

今回は、Pythonの軽量Webフレームワークである **Flask** を使って、  
最小構成のWebアプリを作成し、ローカル環境での動作確認までを行いました。

- Flaskの導入
- `app.py` の作成と基本的な構文
- `localhost:5000` でのWebブラウザ表示
- `host="0.0.0.0"` の意味や、debugモードの注意点

など、**Flaskの基本的な使い方と開発環境での確認**について触れてみました。

※ 今回は開発用のサーバ（`app.run()`）で動作確認を行っていますが、
本番環境では Gunicorn などの WSGIサーバと連携するのが一般的です。
そのあたりは次回以降で解説予定です。


## 次回予告｜【Nginx編】Flaskアプリを外部公開する方法

次回は、今回作成したFlaskアプリを **Nginxと連携させて外部公開する方法** を紹介します。

- リバースプロキシの基本
- Nginxのインストールと設定ファイル
- ポートフォワーディング・UFWの制限緩和

など、**インターネットからアクセスできるWebサービスとして公開する**ための構築ステップを投稿予定です。

---
また、GitHubに誰でも試せるようにコードを公開しています。
今回の`app.py`ファイルを投稿してみたので、良ければ見てみてください
URL : https://github.com/Termnix-IT/Python_Flask_Web_Basic
Go言語におけるクロージャー



```go
package main

import (
    "fmt"
)

func Later() func(string) string {
    var history []string  // 履歴を保持するスライス
    var currentIndex int // 現在の位置を追跡
    
    return func(next string) string {
        // 新しい値が空でない場合、履歴に追加
        if next != "" {
            history = append(history, next)
            currentIndex = len(history) - 1
        }
        
        // 履歴が空の場合、空文字列を返す
        if len(history) == 0 {
            return ""
        }
        
        // 現在の位置の値を返す
        return history[currentIndex]
    }
}

func main() {
    f := Later()
    
    // 基本的な使用例
    fmt.Println(f("Hello"))   // Hello
    fmt.Println(f("World"))   // World
    
    // 空文字列を渡すと現在の値が返される
    fmt.Println(f(""))       // World
    
    // 新しい値を追加
    fmt.Println(f("Go"))     // Go
    
    // 再び空文字列を渡すと最後の値が返される
    fmt.Println(f(""))      // Go
}
```

```mermaid
sequenceDiagram
    participant メイン
    participant 後で関数
    participant クロージャー
    Note over 後で関数: 初期state: []string{}
    
    メイン->>後で関数: f := Later()
    後で関数-->>メイン: 新しいクロージャー
    
    メイン->>クロージャー: f("Hello")
    Note over クロージャー: history = ["Hello"]<br/>currentIndex = 0<br/>return "Hello"
    クロージャー-->>メイン: "Hello"
    
    メイン->>クロージャー: f("World")
    Note over クロージャー: history = ["Hello", "World"]<br/>currentIndex = 1<br/>return "World"
    クロージャー-->>メイン: "World"
    
    メイン->>クロージャー: f("")
    Note over クロージャー: history = ["Hello", "World"]<br/>currentIndex = 1<br/>return "World"
    クロージャー-->>メイン: "World"
    
    メイン->>クロージャー: f("Go")
    Note over クロージャー: history = ["Hello", "World", "Go"]<br/>currentIndex = 2<br/>return "Go"
    クロージャー-->>メイン: "Go"
    
    メイン->>クロージャー: f("")
    Note over クロージャー: history = ["Hello", "World", "Go"]<br/>currentIndex = 2<br/>return "Go"
    クロージャー-->>メイン: "Go"
```



- `currentIndex` は履歴内の現在位置を指し示します（0から始まるインデックス）
- 空文字列（`""`）を渡すと、新しい値は追加せずに現在の値が返されます
- `history` スライスは新しい値が追加されるたびに自動的に拡張されます



**クロージャーの構造**
 ```go
func Later() func(string) string {
    var history []string      // 履歴を保持するスライス
    var currentIndex int     // 現在の位置を追跡
    
    return func(next string) string {
        // 新しい値が空でない場合、履歴に追加
        if next != "" {
            history = append(history, next)
            currentIndex = len(history) - 1
        }
        
        // 履歴が空の場合、空文字列を返す
        if len(history) == 0 {
            return ""
        }
        
        // 現在の位置の値を返す
        return history[currentIndex]
    }
}
```

 主要な特徴- 複数の変数（`history` と `currentIndex`）をクロージャー内で管理 
- 状態の永続化と操作機能を提供
- より実用的なユースケースに対応可能

 状態管理の仕組み- `history`: 文字列の履歴を保持するスライス
- `currentIndex`: 現在参照中の履歴の位置を追跡
- 新しい値の追加時に自動的に更新

 実用的な応用例- コマンドヒストリーの実装
- バックアップシステムの作成
- ステートマシンの実装

 拡張性この基本構造を基に、以下のような機能を追加できます：

- 履歴の最大サイズ制限
- 履歴の検索機能
- 状態の永続化（ファイル保存など）

このようなクロージャーによる実装は、データのカプセル化と状態管理を効果的に行うことができます。
2025 Micro Hardening Basic 参加記録

# 初めに
　今年もHardeningの季節がやってきました。ということで今回もMicro Hardening Basic にオンラインで参加させていただきました。ありがとうございます。前回の参加記録も見ていただけると嬉しいです！

 https://qiita.com/irei0302/items/ee73f410bc70555d2d0b

## Micro Hardening Basicとは
セキュリティをゲーム感覚で学ぶ競技 Micro Hardening の超入門編です。

参加者(皆様)は販売サイトの運営の主人公となり、迫りくる攻撃(不正アクセス、データ改ざんなど)から防衛し、スコアを競います。2人1組のチーム戦となります。(3人1組になる可能性もあります)

== 攻略難易度 ==
Micro Hardening v1, v2では販売サイトを運営するスキル (Webサーバやデータベース、Wordpress管理など) が求められますが、初学者にはなかなか難しかったという声からBasic版が誕生しました。感覚的な攻略推奨レベルは下記のとおりです。

Micro Hardening Basic (攻略推奨レベル 3) [今回]
Micro Hardening v1 (攻略推奨レベル 10) 
Micro Hardening v2 (攻略推奨レベル 15)

引用元（https://sc4y.connpass.com/event/316767/）

上記に書いてある通り超入門編、前回参加した経験があったので今回はHardening競技初参加の同級生1人と超優秀な下級生１人の計３人で競技に挑みました。

事前準備等に関しては前回の記事に書いてある通りに進めていきました。また、競技内容も昨年と同じように感じたので今回の記事では反省点等を中心に書いていこうと思います。

※**来年度も開催されるはずなので技術的要素（実際に行ったセキュア化、コマンド等）はネタバレになる可能性があるので書きません。ただ文から推測ができる可能性があるので「事前情報なしでまっさらな状態で参加したい！」という方はブラウザバックをお願いします。**

# 反省点
* **何もすることがなかった**
反省点といっていいのかわかりませんが何もすることがありませんでした。というのも2人が初参加とは思えない優秀さで、特に下級生の子がLinux触りたてのはずなのに自分よりスラスラとコマンドを打っていて何もすることがありませんでした。
 
&#13;&#10;

* **設定ファイルを触るときは慎重に**
設定ファイルを編集しているときに記述ミスがあり、それに気づかずにサービスを再起動してしまいECサイトが止まってしまいました。
 
&#13;&#10;

* **AIと喋りすぎ**
セキュア化をするために質問をしたのにAIと喋るのが楽しくなって競技そっちのけでお喋りしてしまいました。多分AIをギャルにしたのが失敗ですね。

&#13;&#10;

* **スクリーンショット等記録を残さなすぎ**
Hardening競技に参加して参加記録を書くたびに書いていると思います。競技前は意識して記録取ろうといっていてもいざ始まると忘れてしまうんですよね。気を付けます。

&#13;&#10;

* **何となくでやろうとする**
ログイン失敗のログがあり、127.0.0.1が失敗していてループバックアドレスなのにも関わらず「失敗してるからヤバい奴だろufwでブロックしよ」と思ってブロックしようとしてしまいました。途中で気づいたので良かったですが...何をしているんだろうか。自分でもよくわかりません。

&#13;&#10;

* **違う環境のコマンドをそのまま打ち込む**
これは事前準備の段階で本番環境ではUbuntuなのに何故かAlma Linux でコマンドの確認をしていました。前日に気づいて修正できる部分はしましたがそれ以外は事前確認なしで打ち込んでいました。

&#13;&#10;

* **競技に関係のない話をしていた**
関係のない話をしていた気がします。集中します。

&#13;&#10;

* **プロセスの確認**
不審なプロセスの確認を怠っていました。メンバーが気づいてくれましたが自分でも確認するようにします。

&#13;&#10;

* **パスワード管理**
「パスワード変更とかは先にやろう」とメンバーに言っておきながら自分の使用しているユーザーの変更を忘れていました。

&#13;&#10;

* **パーミッションの確認**
完全に忘れていました。AIが教えてくれるまで完全に忘れていました。

&#13;&#10;

* **ログ**
ログに関してAIに聞いていたら話すのが面白くてログを見ていませんでした。

# 良かった点
* **コミュニケーション**
競技中もコミュニケーションをとり続けながら作業に取り掛かれたので良かったと思います。
コミュニケーションをとることによって進捗を整理したり、質問しやすい環境が作れたりするので改めて大切だなと思いました。初対面ならなおさら大切なのではないでしょうか。

&#13;&#10;

* **事前準備**
事前準備には力をいれていたので本番何をするのか、コマンドは何を打てばいいのかと困ることがなかったので良かったです。準備に関してはやりすぎぐらいがちょうどいいですね。

# まとめ
反省点をまとめてみましたがどれも基礎的なことばかりですね。
基礎的なことでもできていないことが多いなと感じました。まだまだセキュリティ初心者なので基礎から勉強しなおしていこうと思います。
10月のHardening競技に参加したいなと考えているので選考を通過しないと始まりませんがそれまでに勉強し続けていこうと思います。
ハードリンクとシンボリックリンクの違いをまとめる

## iノードとは？

ファイルやディレクトリのメタデータがファイルごとに格納されている領域のことである。メタデータは以下の内容のことである。

- メタデータの内容
    - ファイルの所有者
    - パーミッション
    - ファイルサイズ
    

各ファイル、ディレクトリは固有のiノードが割り当てられる。システム上はこのiノード番号でファイルやディレクトリを識別している。

## ハードリンク

ハードリンクは、1つのiノード番号に複数のファイル名を結びつける仕組みである。

### **仕組み**

- ハードリンクを作成すると、新しいファイル名が作られるが、それは既存のファイルと**全く同じiノード番号**を指す。そのため、ハードリンクの作成元とハードリンクしたファイルを区別することはできない。

図1を見ると、file1.txtとfile2.txtは同じiノード番号であり、どちらもデータの中身が”Hello”である。

![ハードリンク.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750206/141a741e-7fc2-41a6-9aff-a6f8f6c682a5.png)
図1 : ハードリンクの仕組み


```bash
$ ls -li file1.txt
33714422 -rw-r--r--  1 user group 6  6月 21 11:00 file1.txt

$ cat file1.txt
Hello!

# ハードリンク作成
$ ln file1.txt file2.txt

# iノードとリンクカウントを確認 (-li)
$ ls -li
33714422 -rw-r--r--  2 user group 6  6月 21 11:00 file1.txt
33714422 -rw-r--r--  2 user group 6  6月 21 11:00 file2.txt
```

- iノード番号が一致している
- リンクカウントが1から2に増えている。

## シンボリックリンク

シンボリックリンクは、特定のファイルやディレクトリのパスを内容として持つファイルである。

### **仕組み**

シンボリックリンクを作成すると、作成したそのファイルは新しい固有のiノードを持つ。そのファイルの実データ部分に、リンク先のファイルパスが文字列として記録される。そのため、シンボリックリンクにアクセスすると、そのパスをたどって、目的のファイルにアクセスする

図2を見ると、link.txtとfile1.txtはそれぞれ固有のiノード番号を持っている。link.txtの実データは「path/to/file1.txt」というパス情報であり、file1.txtの実データが「Hello」である。link.txtを読み込むと、システムがパス情報をたどってfile1.txtの内容を表示する。

![ハードリンクとシンボリックリンク.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750206/e2adfaab-cdf4-4d99-a778-2f11c06fec2e.png)
図2: シンボリックリンクの仕組み




```bash
# シンボリックリンクの作成
$ ln -s file1.txt link.txt

$ ls -li
33714422 -rw-r--r--  1 user group 6  6月 21 11:00 file1.txt
44556677 lrwxrwxrwx  1 user group 8  6月 21 11:05 link.txt -> file1.txt
```

- iノード番号が file1.txt (33714422) とは**別** (44556677)になっている
- リンクカウントが1
- link.txt -> file1.txt でリンク先パスが表示されている。

## リンク元を削除したとき

上記で作成したfile2.txtとlink.txtを使い、リンク元であるfile1.txtを削除した場合について

### ハードリンク

file1.txtという名前が消えるだけで、iノード 33714422 は file2.txt によってまだ参照されている。リンクカウントが 2 ⇒ 1 に減るだけである。最後のリンクが削除され、リンクカウントが 0 になった時点で実データが削除される。

```bash
# まず、リンク元の file1.txt を削除
$ rm file1.txt

# file2.txt の中身を確認
$ cat file2.txt
Hello!

# file2.txt の iノードとリンクカウントを確認
$ ls -li file2.txt
33714422 -rw-r--r--  1 user group 6  6月 21 11:00 file2.txt
```

### シンボリックリンク

link.txt に記録されたパス "file1.txt" が指す先がなくなるため参照できなくなる。また、リンク先が名前変更された場合も参照できなくなる。

```bash
$ ls -li link.txt
44556677 lrwxrwxrwx 1 user group 8  6月 21 11:50 link.txt -> file1.txt

$ cat link.txt
cat: link.txt: No such file or directory
```

- catコマンドがエラーを返している。これはfile1.txtが削除されたため、リンク切れの状態になっている

### 参考

- [https://e-words.jp/w/iノード.html](https://e-words.jp/w/inode.html)
- https://qiita.com/katsuo5/items/fc57eaa9330d318ee342