OmniAICreator/Qiita-1.07M huggingface dataset:
身体性をまとう人工知能 (1)

> この動画をみてください。まず動画の特異な部分を客観的に整理してください。
> その上でロボットの将来とOpenAIというテーマで未来予想をしてください。

<iframe width="560" height="315" src="https://www.youtube.com/embed/Sq1QZB5baNw?si=sxwAVkjVKn7zx6Vm" 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>

# OpenAIとFigure 01が示す“思考するロボット”の未来

動画「Figure 01 + OpenAI」を拝見しました。以下に、まず客観的な特異点の整理を行い、その後「ロボットの将来とOpenAI」というテーマで未来予想を述べます。

## 動画の特異な部分（客観的な整理）

動画では、Figure社のヒューマノイドロボット「**Figure 01**」とOpenAIの協業成果が紹介されています。以下が特異なポイントです：

1. **音声と視覚による人間との自然な対話**

     - 人間の問いかけに対し、ロボットが**映像から物体を認識**し、**意味を理解した上で応答**。
     - 例：「What is this？」という質問に対し、「It looks like an apple.」と答える。
2. **ロボットの自己判断とタスク遂行能力**

     - 単に言語で答えるだけでなく、指示に応じて**物を取り上げたり、移動したり**する。
     - 例：「Can you hand me something to eat?」という曖昧な依頼にも適切に反応し、食べられるもの（リンゴ）を選択して手渡す。
3. **リアルタイムでの推論とマルチモーダル理解**

     - 静的なスクリプトでなく、**視覚・聴覚・運動・言語**を統合して、その場で「推論」しているように見える。
     - GPT-4を活用したような**マルチモーダルAIの実装例**。
4. **流暢で温かみのある発話スタイル**
     - ロボットの声に感情がこもっており、「機械的な応答」ではなく、**人間的な対話**に近づいている。

## ロボットの将来とOpenAIというテーマで未来予想

Figure 01のような事例は、「人型ロボット × マルチモーダルAI × 音声対話」の融合が急速に進んでいることを示しています。これを踏まえ、以下のような未来が予想されます。

1. **家庭・店舗・医療など、実社会への本格展開**

     - 高齢者介護、子育て支援、飲食店での接客、医療現場でのアシスト等、**人手不足を補う形で実用化**。
     - 特に、曖昧な指示を理解して柔軟に動ける点が、「マニュアルでは対応しづらい現場」での導入を加速させる。
2. **ロボットが「考える存在」になる転機**

     - 従来の「動く道具」から、「**意味理解と意志決定ができる相棒**」へと進化。
     - OpenAIが提供するマルチモーダルな理解能力が、その中核技術に。
3. **ロボットとの共創時代**

     - 人とロボットが**対話でアイディアを出し合い、共に問題解決**する未来。
     - 特に教育・研究・芸術の分野で、創造的なロボットが出現。
4. **新たな社会的課題も**

     - 感情的なつながりが生まれることで、「ロボットに依存する」「ロボットを擬人化しすぎる」などの心理的リスク。
     - 法的枠組み（責任の所在やプライバシー）も再整備が必要に。

## 総括：OpenAI × Figureのもたらす未来像

「思考するロボット」が現実のものとなりつつあります。
今後は「**言語AIの知性**」と「**ロボットの身体性**」が融合し、**人類の行動半径・想像力を拡張**する存在となるでしょう。
そして、OpenAIのようなAI基盤企業は、OSや知能の「心臓部」として、あらゆるロボットの中に入り込み、「無数の身体を持つ知性」として社会を構成していくと予想されます。

 -> [(次の記事 (SFでのAIのリスト))](https://qiita.com/shinya_ohtani/items/54cc380bf348ddf75fc6)
FlutterとAndroidStudioの機能

# はじめに
Android StudioでFlutterの開発をする際に役立つツールについてまとめていきます。
Roadmap.shのFlutter→AndroidStudioの学習内容に沿って記載しています。

## Flutter widget inspector
FlutterアプリのUIをリアルタイムでデバッグし、ウィジェットのプロパティやレイアウトを詳細に調査するためのツール

### 確認方法
右端のFlutter Inspectorをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641068/ff87ea2c-b19d-50c0-a6e9-9bf3b0cfebd1.png)

### 概要
既存のレイアウトの理解やレイアウトの問題を発見し、視覚的にデバックを行うことが可能。機能としてはレイアウトのガイドラインを表示したり、テキストのベースラインを表示して整列されているかを確認することも可能。

**参考**

https://docs.flutter.dev/tools/devtools/inspector

## Flutter outline
Flutterアプリのコード構造を視覚的に表示するツール

### 確認方法
右端のFlutter outlineをクリックしたところ以下の表示が出たので、その方法に沿って確認を行います。

>原文：The Flutter Outline window is being removed soon. Use the Structure view instead: View -> Tool Windows -> StructureThe refactorings in the Outline view can be found in the editor as Context Actions ⌥⏎ (macOS) / Alt+Enter (Windows/Linux)

>日本語訳：Flutterのアウトラインウィンドウは近日中に削除されます。代わりに構造ビューを使用してください：表示 -> ツールウィンドウ -> 構造。アウトラインビューのリファクタリングは、エディタ内のコンテキストアクション ⌥⏎ (macOS) / Alt+Enter (Windows/Linux) で見つけることができます。

メニューからView -> Tool Windows -> Structure
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641068/625d7b7f-0c99-226b-5c66-de7e16ecc0a5.png)


### 概要
コードの変更が即座に反映され、ウィジェットツリーの階層構造を表示する。特定のウィジェットや要素に素早くアクセスすることが可能。

## Flutter rendering tree
いまいちどのツールを指しているのかわかりませんでした。
調べても描画の仕組みについての話がヒットしてしまい...わかり次第更新します

## Flutter performance tool
Flutterアプリのパフォーマンス問題を診断し、最適化するためのツール

### 確認方法
右端のFlutter performanceをクリックしたところ以下の表示が出たので、その方法に沿って確認を行います。
>原文：The performance panel is being removed soon. Use the Flutter DevTools panel instead: View -> Tool Windows -> Flutter DevTools

>日本語訳：パフォーマンス パネルはまもなく削除されます。代わりに Flutter DevTools パネルを使用してください: 表示 -> ツール ウィンドウ -> Flutter DevTools

メニューからView -> Tool Windows -> Flutter DevTools
…なぜかFlutter DevToolsが見つからなかったため↓からアクセスを行いました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641068/edd54dc8-f517-3943-efb1-efb59d24e567.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641068/ace4e97f-0707-23d6-03af-d515e38ef3c0.png)



### 概要
チャートは、アプリケーションのFlutterフレーム情報を表示する。アプリで新しいフレームが描画されると更新され、UIスレッドやRasterスレッドで行われる作業をバーの色分けで表している。どの部分で時間がかかっているかを視覚的に把握することが可能。

:::note info
UIスレッド: ユーザーインターフェースの描画に関連する作業。
ラスタースレッド: 画像の描画やピクセルの処理に関連する作業。
:::

**参考**

https://docs.flutter.dev/tools/devtools/performance#flutter-frames-chart

## Flutter layout explorer
Flexウィジェットとその子ウィジェットがどのようにレイアウトされているかを視覚化するツール

### 確認方法
右端のFlutter Inspector -> layout explorer
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641068/ff87ea2c-b19d-50c0-a6e9-9bf3b0cfebd1.png)

### 概要
Flutter Inspector内の1機能。ウィジェットのプロパティを調整することで、レイアウトの問題を迅速に特定し、修正することが可能。

# おわりに
実際にアプリ制作をしていてFlutter Inspectorは良く使用していましたが、その他のツールはあまり使用してきませんでした。
今回初めて知るツールもあったため今後は活用していこうと思います。
【PowerDNS】 バージョンアップしたらエラーで返答しなくなった

サーバを CentOS 7 から Oracle Linux 9 に移行しているので、移行する PowerDNS やバックエンドの PostgreSQL も当然バージョンアップになります。

今回は、以下のようなバージョンアップになりました。

旧:

- pdns-3.4.10-1.el7.x86_64
- pdns-backend-postgresql-3.4.10-1.el7.x86_64
- postgresql-server-9.2.15-1.el7_2.x86_64


新:

- pdns-4.8.4-1.el9.x86_64
- pdns-backend-postgresql-4.8.4-1.el9.x86_64
- postgresql-server-13.20-1.el9_5.x86_64

---

DBのダンプ&リストアも順調にいって、pdnsも普通に起動したのですが、dns問い合わせをすると返答が正常に返ってきません。

/var/log/messages を見ると、以下のようなエラーが出てました。

```
Mar 19 14:52:12 XXXXXXXXX pdns_server[XXXXX]: Exception building answer packet for www.example.com/A (Parsing record content (try 'pdnsutil check-zone'): Data field in DNS should start with quote (") at position 0 of 'v=spf1 ip4:XXX.XXX.XXX.XXX -all') sending out servfail
```

旧バージョンでは SPF レコードの content はダブルクオーテーションで囲ってなかったのですが、新しいバージョンではそうする必要があるようです。

`psql pdns` から当該レコードのIDを求めて、

```
update records set content='"v=spf1 ip4:XXX.XXX.XXX.XXX -all"' where id=XX;
```

とすることで復旧しました。

---

そもそも、このDNSレコードは type が SPF (DNS record type 99) となっており、deprecatedなので、削除してしまっても良かったかもしれないです。ちなみに TXT で同一のレコードが存在してました。

---

以上
俺は、「女子に」うける、サウンドメーターを作る(1)企画


目的
----

- 展示、即売会で「半ズボン美少年」や「キロット美少女」に光るアクセサリーやサウンドレベルメータが受けていた。
- 俺も、「天才」なので、これくらい簡単に作れるとおもひ
- ぼう、東側諸国の様に原理原則に忠実に
- デザイン性は、排除して
- 高速、軽量、分かりやすさ重視
- 女子などへのアンケート(いつ、だれ?)では、電子工作系は、簡単、すごい、安い
- カセット、カードリッジ、マガジン方式でカチャット(西側仕様)
- マイク内蔵で配線不要
- オートゲーンで音量調整不要(できれば、いいな)
- 安価なSSD1306を使用(秋月112031)
- 1000円程度(たぶん、オーバー)
- 縦置き
- 走査ブロック(SSD1306の用語でページ)をそのまま利用して8チャンネル(固定)
- 任意の図形
- (カラー)白黒だけどカラーセロハンでインべーター方式
- 長期記事
- ノーバッファー(ノーVRAM)
- SSD1306をダイレクトドライブ(秋月のやつ)
- 名刺さいず
- 大きさは、正方形、インチサイズ、インチ2.5mm、1/2,2/3は、OK、(西側、東側ともに)(ややミリ規格に振る)(誤差は考えない)2インチぐらい(5cm)
- 目標は、20250405のスタックチャンフェスまで(ならいいな)
- 今日、ガジェットメイドカフェ、(20250226)水物を飲みすぎてパワーアップする



図
----

![o_coq844.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/d761c4dd-e832-42ef-9a9e-9e1df85e4855.jpeg)


![o_coq845.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/4e98f4ce-4306-47a9-8e26-e183712ec773.jpeg)

4チャンネル+4チャンネル使用した時

![o_coq846.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f4e02144-c6f2-4900-a8f3-e56974314217.jpeg)
Unity-外部フォントを使う方法

外部からフォントをダウンロードする
（Defont.comや、UnityAssetStoreから）
Window->TextMeshPro->Font Asset CreaterのWindowを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4007510/a2f1a918-130b-4c73-9452-887c4f97d4dd.png)
Source Fontの欄に、ダウンロードしたもののうち、.otfもしくは.ttfファイルを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4007510/08a97475-2193-4b22-b854-9a4008fb3317.png)
（やりたければ設定をいじる）
Generateする
あとはTextのFontのところに、Generateしたものをいれればオッケー
RailsでDBで保存されている日付とレスポンスされてきたJSONの日付がなんか違う時

# はじめに
どうも、**torihazi**です

今日は気にしなくていいかもしれないけど

気にする人は気にしそうだったので仕方なく調べました。

# 何が起きたの。
DBでは

> 2025-03-25 15:00:00

と保存されているのに、Rails APIモードで出力したJsonには

> 2025-03-26T00:00:00.000+09:00

となんか1日進んじゃっていたという事象。

# 結論
タイムゾーンの違い。

DBには「2025-03-25 15:00:00」という形式でUTCタイムゾーンで保存される。

で今回、アプリケーションのタイムゾーンはconfig.time_zone = 'Tokyo'で東京時間（UTC+9）に設定されてた。

そこからUTCの15:00に9時間を足すと翌日の00:00（15:00 + 9:00 = 24:00 = 翌日の00:00）

そのため「2025-03-25 15:00:00 UTC」は「2025-03-26 00:00:00 JST」と同じ時刻。

Railsは日時データをJSONに変換する際、ISO 8601形式（`YYYY-MM-DDThh:mm:ss.sss+TZ`）を使用する。

そのため最終的に「2025-03-26T00:00:00.000+09:00」という形式になる。

Railsでは、明示的に設定されていない場合：

config.active_record.default_timezone = :utcがデフォルトで、DBにはUTCで保存される。

JSONシリアライズ時にはconfig.time_zoneで設定されたタイムゾーン（この場合は東京時間）に変換される。

つまり、同じ時刻を表していますが、タイムゾーンの変換により日付が変わって見えちゃったということ。

# 解決策
Railsのアプリケーション側では time_zone = 'Tokyo'してたので

DBの方もTokyoのタイムゾーンになるようにする。

ということで config/application.rbにおいて下記を追記。

```
    config.time_zone = 'Tokyo'
    config.active_record.default_timezone = :local <= これね
```

これでokっす。

# 終わりに
レスポンスも正常になったのでよかったよかった。

とにかくタイムゾーンを疑いましょう。
新規開発準備あれこれ　- .gitkeepとweb hook

最近新しく個人開発を数名で始めることになり、インフラ整備を進めている。
本記事は今回やったことのメモ。
ソースコード管理にはgithub、コミュニケーションツールにはdiscordを使用している。

## 空のフォルダをコミットしたい
・新しいリポジトリを作成して、ディレクトリ構成を決めたので、空のフォルダを作ってコミットしたい
・だが、gitではデフォルトで空のフォルダがコミット対象から外されてしまうのでコミットすることができない

### やったこと
・空のフォルダにそれぞれ.gitkeepファイルを配置する
・.gitkeepは、「デフォルトではファイルが存在しないけれど、ファイルが追加されたら、そのファイルを Git での管理対象にしたい」場合に使う
・「デフォルトではファイルが存在しないし、そこに作られたファイルもバージョン管理したくない」場合は、.gitignoreを利用するらしい
参考：　https://qiita.com/ndxbn/items/f124d2b183b60cb074e2

## githubのリポジトリのイベントをdiscordに通知したい
・pushやメンバー追加などのイベントを拾ってdiscordに通知が来るようにしたい。
![スクリーンショット 2025-03-26 21.43.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092540/c3648946-8ead-44c5-9623-56acf96e2a63.png)

### やったこと
1. discord上に通知用チャネルを作成（例：#github）
1. 作成したチャネルの歯車マークをクリックして、設定画面からIntegration>Webhooksを選択
1. [New WebHook]をクリックし、新規のWebHookを作成
1. NAMEは"GitHub"などに設定。CHANNELはデフォルトで作成した#githubになっているはずなのでそのまま。そうでなければ通知先チャネルを設定
1. [CopyWebHook URL]でURLをコピー
1. 通知を拾いたいgithubのリポジトリの設定画面を開く
1. WebHooks>[Add Webhook]を選択、[PayLoad URL]に"先ほど取得したURL/github"を入力
1. [content type]をapplication/jsonに設定
1. [Which events would you like to trigger this webhook?]で拾いたいイベントを選択
1. [Update Webhook]で作成完了
1. 試しにプッシュしてみて、指定したチャネルに通知が届けば成功

参考：　https://mekurun.com/tips/discord-github/
#0081（2024/03/26）GraphQLとは

# GraphQLとは？使い方とREST APIとの違いを徹底解説

GraphQL（グラフキューエル）は、Facebookが開発したAPI向けのクエリ言語およびランタイム環境で、クライアントが効率よく柔軟にデータを取得できる仕組みを提供します。本記事では、GraphQLの基本的な概念や使い方、従来のREST APIとの違いについて解説します。

---

## 🔹 GraphQLの特徴

GraphQLは以下のような特徴を持ちます。

- クライアント側が必要なデータのみを指定して取得可能
- 単一エンドポイントで効率的なデータ取得を実現
- データ取得の際のオーバーフェッチやアンダーフェッチを回避

---

## 🔹 REST APIとの比較

REST APIには次のような問題点があります。

- **オーバーフェッチング（過剰取得）**：不要なデータまで送信される
- **アンダーフェッチング（不足取得）**：必要なデータが複数のエンドポイントに散らばる

GraphQLでは、以下のようにREST APIの問題を解決します。

| 項目 | REST API | GraphQL |
|------|----------|---------|
| エンドポイント数 | 複数エンドポイント | 単一エンドポイント |
| 取得データ | サーバ側が定義した形式 | クライアントが自由に指定 |
| ネットワーク効率 | 必要以上のデータ取得あり | 必要なデータのみ取得 |

---

## 🔹 GraphQLの具体的な使い方

### クエリ例

例えば、「ユーザーの名前と投稿した記事タイトルのみ取得する」場合のクエリ例です。

```graphql
query {
  user(id: "123") {
    name
    posts {
      title
    }
  }
}
```

### サーバーレスポンスの例

```json
{
  "data": {
    "user": {
      "name": "田中太郎",
      "posts": [
        { "title": "GraphQL入門" },
        { "title": "REST APIとの違い" }
      ]
    }
  }
}
```

---

## 🔹 GraphQL API構築方法

### Step 1: スキーマ定義

APIのデータ構造をスキーマとして定義します。

```graphql
type Query {
  user(id: ID!): User
}

type User {
  id: ID!
  name: String!
  posts: [Post!]!
}

type Post {
  id: ID!
  title: String!
  content: String
}
```

### Step 2: リゾルバ作成

クエリ実行時にデータ取得処理を行うのがリゾルバです。

```javascript
const resolvers = {
  Query: {
    user: (_, { id }) => {
      return getUserById(id);
    },
  },
  User: {
    posts: (user) => {
      return getPostsByUserId(user.id);
    },
  },
};
```

---

## 🔹 メリットとデメリット

### メリット
- 必要なデータだけを取得できる
- 柔軟なクエリ設計が可能
- クライアント側の柔軟性とネットワーク効率が向上

### デメリット
- クエリが複雑化する可能性がある
- キャッシュ戦略やパフォーマンス最適化の工夫が必要
- 初期のスキーマ設計に手間がかかる

---

## 🔹 GraphQLが使われる代表的な環境

- クライアントサイド：React（Apollo Client、Relay）、Vue.js、Angularなど
- サーバーサイド：Node.js（Apollo Server、Express GraphQL）、Python（Graphene）、Ruby（graphql-ruby）、Java（graphql-java）など

---

## 🔹 まとめ

GraphQLは、REST APIが抱える課題を解決し、クライアント側がより柔軟で効率的にデータを取得できるよう設計された技術です。API設計やフロントエンド開発において、GraphQLを選択肢の一つとして検討してみてください。
やっと走り始めた気分

Udemyを見終わり(7割理解できていない)
やっと作成を始めました。

方法は簡単
1.Udemyのソースコードをダウンロード
2.Eclipseに張り付け
3.自分の作成するプロジェクトを作成
4.Udemyのソースコードをそのまま移行
5.自分の作りたいものに少しづつ修正を加える！

ほら、コピペエンジニアの誕生です()

でも作るのが少し違うので頭を使いました。
後の自分にアドバイス

・サーブレットとJSPが何たるかを調べろ
・Javaの文法を思い出す時間を使え
・何でもかんでもChatGPTに聞くな

備忘録
・パラメーターの転送(リクエストスコープでの受け渡し)はできた。
　から次はDBの連携を学びつつ一通りの機能を実装できるようになれ
 ・早くSQLを勉強しろ！！！！！！

 技術的な備忘録は理解が出来ていないので書けません。
 これからはそういうのも残していきたい。
#0080（2024/03/26）PythonのUvicorn

# PythonのUvicorn（ユビコーン）とは？

`uvicorn`はPythonで書かれた高速で軽量なASGI（Asynchronous Server Gateway Interface）サーバーです。主に非同期Webアプリケーションを実行するために使用され、特にFastAPIやStarletteなどの非同期フレームワークと組み合わせて利用されます。

---

## 🔹 Uvicornの特徴

Uvicornの主な特徴は次の通りです。

- **非同期処理**：Pythonのasyncioを活用し、高速な処理が可能
- **軽量かつ高速**：オーバーヘッドが少なく、高パフォーマンス
- **対応プロトコルの幅広さ**：HTTP/1.1、HTTP/2、WebSocketに対応
- **使いやすさ**：シンプルでわかりやすいインターフェース

---

## 🔹 Uvicornのインストール方法

pipを使用して簡単にインストールできます。

```bash
pip install uvicorn
```

---

## 🔹 Uvicornの使い方（FastAPIとの例）

### FastAPIアプリの例

```python
# main.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def read_root():
    return {"message": "Hello, World!"}
```

### サーバー起動方法

次のコマンドを実行し、サーバーを起動します。

```bash
uvicorn main:app --reload
```

- `main`は作成したPythonファイル名（main.py）
- `app`はFastAPIインスタンス
- `--reload`オプションは、コード変更時の自動リロードを有効化します（開発時に便利）

サーバー起動後、ブラウザで`http://127.0.0.1:8000`にアクセスすると動作確認できます。

---

## 🔹 他のWSGIサーバー（Gunicorn）との比較

| 項目 | Uvicorn | Gunicorn |
|------|---------|----------|
| プロトコル | ASGI（非同期） | WSGI（同期） |
| パフォーマンス | 高速（非同期処理に適している） | 安定的だが非同期処理に不向き |
| 主な用途 | FastAPI、Starletteなど非同期フレームワーク | Django、Flaskなど同期フレームワーク |

### UvicornとGunicornの併用例

Gunicornを使用してUvicornを動作させる場合は以下のようにします。

```bash
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker
```

- `-w 4`：4つのワーカープロセスを作成
- `-k uvicorn.workers.UvicornWorker`：GunicornのワーカーにUvicornを指定

この組み合わせで、負荷分散と高速処理を同時に実現できます。

---

## 🔹 まとめ

UvicornはPythonの非同期処理能力を活用し、高性能なWebアプリケーションを実行するためのASGIサーバーです。FastAPIやStarletteなどのフレームワークと相性が良く、リアルタイム通信（WebSocket）や高速API開発に適しています。
typst で画像を横に配置したい

## 方法
Typstで画像を並列に表示するには，`grid`を使う．

```Typst
画像を並列に挿入するよ．
#figure(
  grid(
    columns: 2,
    gutter: 2cm,
    image("sine_wave.png"),
    image("cos_wave.png")
  ),
  caption: [
    sine wave and cosine wave.
  ]
) <fig:fig>
画像を並列に挿入したよ．
```
`gutter` で左右の画像の隙間を調整できる．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642842/9a99d492-c4cf-4a8a-b7e0-1e15a7e42cb1.png)

## 参考文献
- https://stackoverflow.com/questions/75968954/typst-horizontal-display-of-2-images
- https://typst.app/docs/reference/layout/grid/
Dockerコマンド基本

# コマンドとオプションの意味

## コンテナ作成
```sh
docker create -it --name apache-server -p 8080:80 alpine
```

docker create
- 意味：新しいコンテナを「作成」します。ただし、この段階では「起動」はしません
- よく使われる docker run は「作成してすぐ起動」しますが、create は作成だけを行います

-it
これは2つのオプションをまとめたものです：
- -i（--interactive）：標準入力を開いたままにします（ターミナルで操作できるように）
- -t（--tty）：仮想端末（TTY）を割り当てます。シェルっぽく使うために必要です

--name apache-server
- 作成するコンテナに名前を付けます（ここでは apache-server）
- 名前を付けると、docker start apache-server のように呼び出しやすくなります

-p 8080:80
- ポートフォワーディングの設定です
- ホストの8080番ポート を コンテナの80番ポート に接続します
- つまり、ブラウザで `http://localhost:8080` にアクセスすると、コンテナ内の 80番ポート に届きます


alpine
- 使用するイメージ名です。alpine は非常に軽量なLinuxディストリビューションのDockerイメージです
- ただし、この状態では Apacheは入っていません
- Apacheを動かしたい場合は、alpine イメージに自分でApacheをインストールするか、httpd イメージ（Apache公式）を使う方が簡単です


## コンテナを作成して中に入る
```sh
docker run -it --name apache-server -p 8080:80 alpine /bin/sh
```
- --name apache-server：名前を付けます
- -p 8080:80：ポートフォワーディング
- /bin/sh：シェルを起動（AlpineはBashがないので sh）


## イメージのビルド
```sh
docker build -t my-apache-alpine .
```
- -t my-apache-alpine：イメージ名を my-apache-alpine に設定
- . は「カレントディレクトリ」を指定


## コンテナの起動
```sh
docker run -d --name apache-server -p 8080:80 my-apache-alpine
```
- -d：バックグラウンドで実行
- --name apache-server：名前付け
- -p 8080:80：ポートマッピング


```sh
docker run --rm my-python-app
```
- --rm：実行後にコンテナを削除する（お掃除も自動）
Docker Composeコマンド基本

# Docker Compose

## docker-compose 起動
```sh
docker-compose up -d
```
- -d：バックグラウンド実行
- 初回はビルドされ、その後コンテナが起動します


## 停止＆削除
```sh
docker-compose down
```
- コンテナとネットワークを停止＆削除します（イメージは残る）


## 再ビルドして再起動
```sh
docker-compose up -d --build
```
- --build を付けることで、更新されたファイルでイメージを再構築します


## Docker Compose で作ったコンテナを削除するには？
```sh
docker-compose down --volumes --rmi all
```
- --volumes：関連するボリュームも削除
- --rmi all：ビルド済みのイメージも削除
[Julia]仮想環境（Package）構築

## はじめに

　データ分析や機械学習などに利用できるプログラムとして、Juliaがあると知った。
　以下３点のメリットから今後利用することがあるかもしれないので、備忘録として初歩的なことから欲しかった資料をまとめていく。
　[1]Pythonと同じようにライブラリを利用できる
　[2]実行速度がC言語よりも速い
　[3]PythonやC言語と連携することもできる

## 実行環境
　参考資料[1]で構築したVSCにおけるWSL2で実行している。

## Packageとは

　Pythonではcondaコマンドで仮想環境を構築できると思うが、Juliaでも仮想環境を構築することができ、Packageと呼ばれている。
　Packageを作成コマンドを実行すると、作成コマンドを実行したディレクトリに環境情報が含まれているManigest.toml, Project.tomlが作成され、このファイルを共有することで他の人と仮想環境を共有できることから、Dockerのような役割も担っているらしい。
　今回はあくまでも作成用の最低限のコマンドをまとめていくだけなので、詳細な中身は参考資料[2]など別途資料を確認すること。

## Package作成
### 1.Juliaを起動
```
julia
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1391358/6d4b64a5-c1d8-42d5-a2f8-bdaac8eaf01f.png)

### 2.作業ディレクトリでパッケージをアクティブにする
```
using Pkg
Pkg.activate(".")  # 現在のディレクトリをプロジェクトとしてアクティブにする
```

### 3.パッケージをインストールする
必要なパッケージをインストールしていく
```
Pkg.add("パッケージ名")
```

### 4.成功確認
```
Pkg.status()
```
3でインストールしたパッケージ名が列挙される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1391358/3bbb66e3-c21f-45e6-bc7e-731ea409647a.png)

Manifest.toml, Project.tomlが作成される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1391358/c98dd85c-1cba-4112-a078-6404b5a97548.png)

## 構築後の仮想環境起動
VSCを閉じてから次回作業実施時は、アクティブコマンドを実行すればいい。

## 参考資料
[1]svoboda, 『[Julia]VSCにおけるWSL2でのJulia　環境構築～サンプルコード実行まで』, https://qiita.com/svoboda/items/6a0ad624bc58a354edb3
[2]mametank,　『Juliaのプロジェクトと環境』, https://qiita.com/mametank/items/9fc1c9227303d6ca304b
Dockerよく使うコマンドチートシート

## よく使う掃除コマンドチートシート

| コマンド                         | 説明                          |
|----------------------------------|-------------------------------|
| `docker ps -a`                  | すべてのコンテナ一覧         |
| `docker rm <id>`               | コンテナ削除                 |
| `docker rmi <id>`              | イメージ削除                 |
| `docker container prune`       | 停止中のコンテナ一括削除     |
| `docker image prune -a`        | 未使用のイメージ一括削除     |
| `docker system prune -a`       | 全部掃除                     |
GoエンジニアがGoエンジニアを滅ぼす

# GoエンジニアがGoエンジニアを滅ぼす

こんにちは、世界のエンジニアの皆さん！最近、バックエンドシステムをPHP (+ Laravel) や Ruby on Rails から **Goに書き換える**という話をよく耳にしませんか？今日はそのトレンドにちょっと待ったをかけてみましょう。タイトルの「GoエンジニアがGoエンジニアを滅ぼす」は物騒ですが、中身はもっとユーモラスで鋭い考察です。

## 概要
- PHPやRubyからGoへの書き直しブームを観察（Pythonもあるけど、主流はやっぱりGo？）
- Goが選ばれる性能・型・安全性・マイクロサービス化の理由を検証
- Java, Kotlin, C#, Swift, C++, Rust, Scala, Elixir, TypeScript(Node.js)など他言語はなぜ選ばれない？
- GoやPythonのコードが「金太郎飴」になる問題について
- そして最後に、Goエンジニアが見落としている「不都合な真実」とは……

では、肩の力を抜いてお読みください。

## PHP/RubyからGoへの大リプレイス時代

PHP (+ Laravel)、Ruby on Railsは長くウェブ業界を支えましたが、最近Goへのリプレイスが激増しています。しかし、こんな光景が社内で起きていませんか？

### 社内のリアルな風景
- **リードエンジニアの野望:** 「PHPやRails、もう辛いっす。Goなら速くて保守性も抜群ですよ！」
- **CTOの懐疑心:** 「Goにするメリットって本当にあるの？しっかり検証した？」
- **PMの胸騒ぎ:** 「リライト期間中、納期はどうしよう……。」
- **新人エンジニアの目の輝き:** 「Goで書けるなんて最高っす！」

でも、本当にGoへの書き直しはベストでしょうか？

## Goを選ぶ理由に冷静なツッコミを

### パフォーマンス向上？
Goは確かに速い。でも実際のWebサービスはDBやI/O待ちがボトルネック。PHPやRubyが遅すぎて困ったことあります？

### 型と安全性？
静的型付けは確かに安心。でもPHPもRubyも型の仕組みが進化してるし、TypeScriptだって「そこそこ型安全」程度にはなってますよね？

### マイクロサービス化？
モノリスから分割した結果、複雑性が激増して「分散モノリス化」するケース、多くない？

### 学習コスト？
「Goはシンプル」と言うけど、goroutineやチャネルを全員がすぐ理解できるって本当に？

### エコシステムと未来志向？
Goのエコシステムは確かに素敵。でも必要な機能がPHPやRailsに本当に無いのか、単に「隣の芝生が青い」状態かも？

ちなみにPythonもよく候補になりますが、バックエンドとしての人気よりも、近年は特に機械学習や生成AIの分野での存在感が圧倒的ですよね。

## 他の選択肢を忘れてない？

実際には、多くの魅力的な言語がありますが、それでもGoが選ばれるのはなぜでしょう？

- **Java:** JVMの安定感。でも古臭くてイケてない？
- **Kotlin:** JVM上でモダンだが、サーバーサイドでの実績が少ない。
- **Scala:** JVMで関数型とオブジェクト指向を融合した強力言語。でも難易度も最強。
- **C#:** .NETで堅実。でもウェブ界隈では地味すぎ？
- **Swift:** Apple謹製だけど、サーバーサイドではニッチすぎる。
- **C++:** 圧倒的パフォーマンス。でも開発生産性は壊滅的。
- **Rust:** メモリ安全で高速だが、学習曲線が厳しすぎる。
- **Elixir:** 並行処理は最高クラス。でも採用している会社もエンジニアもニッチすぎる。
- **TypeScript(Node.js):** フロントエンドと統一できるけど、「非同期地獄」に耐えられる？

結局Goが「ちょうど良い」から選ばれるということですよね。

## GoとPythonに共通する「最大の特徴」とそのリスク

Go言語には大きな特徴があります。それは、

**コードが金太郎飴のように、どこを切っても同じ見た目になる特徴があること**です。

実はこの「誰が書いても同じようなコードになる」という特徴はPythonにも共通しています。  
PythonもPEP8やBlackなどによってコードスタイルが強力に統一され、誰が書いても似たコードになるのが強みです。

しかし、これがGoとPythonに共通した、最大の弱点でもあるのです。

## 誰が書いても同じコード = 生成AIが最も得意なコード

「誰が書いても似るコード」は、生成AIが最も得意とする分野です。

最近の生成AIはGoやPythonのコード生成を難なくこなします。つまり、エンジニアたちは無意識にAIが最も書きやすい言語を選んでいるのです。

## さらに皮肉 – Pythonが生成AIを育てている現実

ここで皮肉なのが、生成AIを育てている主役がPythonだという点です。AIのフレームワーク（TensorFlow, PyTorchなど）はほぼすべてPython製。

つまり、「生成AIを育てるPythonエンジニアが、Goエンジニアを滅ぼし、自らも滅ぼしている」という恐ろしい構図が完成しているのです。

## 結論：滅ぶのは「GoやPythonしか書けないエンジニア」

結局のところ、Goへの大量リプレイスがもたらす本当のリスクは、「GoやPythonしか書けないエンジニア」を量産することです。

誰でも書けるコードは生成AIが容易に書けてしまいます。自分の仕事を奪うAIを育てる言語を選び、自ら墓穴を掘っているという皮肉な現実があります。

しかし、柔軟に複数の技術を使いこなし、AIを味方にできるエンジニアなら、次の時代も生き延びられるでしょう。

---

真夜中のオフィス。  
画面には次々とコードが書き込まれていくが、キーボードを叩く音は聞こえない。  
そしてもちろん、その席にエンジニアの姿もない。

──そう、そもそもこの文章を書いたのは生成AIなのですから……。
OpenAIによるAIエージェント構築のためのツール

![](https://storage.googleapis.com/zenn-user-upload/85f25f37ab0f-20250313.png)

OpenAIは最近、開発者やエンタープライズ向けに「エージェント構築のための新ツール」を発表しました。これらのツールは、自律的なAIエージェントの開発をより簡単に実現するためのものです。
今回は、これらの新ツールの詳細について解説します。
https://openai.com/index/new-tools-for-building-agents/

## 主要な発表内容

OpenAIが発表した新ツールは主に以下の要素で構成されています

1. **Responses API**：エージェント構築のための新しいAPIインターフェース
2. **Built-in ツール**：ウェブ検索、ファイル検索、コンピュータ操作
3. **Agents SDK**：オープンソースのエージェント管理フレームワーク

これらのツールは、開発者がより高度なAIエージェントを効率的に構築・デプロイ・スケールするための基盤を提供します。

https://platform.openai.com/docs/guides/agents

## Responses API：新世代のインターフェース

Responses APIは、OpenAIの既存のChat CompletionsとAssistants APIの機能を統合・発展させた新しいAPIです。
この新APIには、以下のような特徴があります

- **複数ツール対応**：複数のツールを同時に利用可能
- **複数ターン対応**：複雑な会話の流れをサポート
- **複数モダリティ対応**：テキスト以外の入出力も処理可能

従来のAPIが主にテキスト入出力を想定していたのに対し、Responses APIはより複雑なインタラクションを簡潔に実装できるよう設計されています。大きな変更の１つは従来のAssistants APIでは多くの初期設定が必要だった機能が、Responses APIではより簡単に実装できるようになったことです。

## Built-in ツール：エージェントの能力を拡張

Responses APIには、すぐに利用可能な3つの強力なツールが内蔵されています

### 1. ウェブ検索ツール

- リアルタイムの情報を取得可能
- AIモデルの事実的正確性を大幅に向上
- 回答の情報源を引用可能

### 2. ファイル検索ツール

- 社内文書やドキュメントからの情報検索が可能
- バックエンドでは自動的にチャンキングや埋め込み（ベクトル変換）を実行
- 開発者は単純なクエリを送るだけで、APIが適切なベクトルマッチングを実行

### 3. コンピュータ操作ツール

- AIがコンピュータと直接インタラクションすることが可能
- API接続がないレガシーアプリケーションの自動操作をサポート
- OpenAIの「Operator」製品と同様の機能を開発者が活用可能

これらのツールは「すぐに使える」形で提供されており、開発者は最初元の設定をすれば機能を実装できます。

## Agents SDK：マルチエージェントワークフローの管理

Agents SDKは、エージェントの構築と管理のためのオープンソースフレームワークです。
以下のような特徴があります

- **軽量設計**：少ない抽象化で簡単に使用可能
- **ワークフロー管理**：複数のエージェント間の連携を調整
- **柔軟性**：OpenAIのモデルだけでなく、他のAIモデルも利用可能

基本的な使用例は次のようになります：

```python
from agents import Agent, Runner

agent = Agent(
    name="Assistant",
    instructions="You are a helpful assistant"
)

result = Runner.run_sync(agent, "Write a haiku about recursion in programming.")
print(result.final_output)
# Code within the code,
# Functions calling themselves,
# Infinite loop's dance.
```

このSDKを使用することで、開発者は複雑なエージェントのオーケストレーションを簡単に実装できます。

## 今後の展開

OpenAIは2026年までにAssistants APIからResponses APIへの移行を計画しています。
開発者は、この移行期間中に新しいAPIへの移行を準備することが推奨されます。

## まとめ

OpenAIの新ツールは、AIエージェントの開発に大きなメリットを提供する可能性があります。Responses API、内蔵ツール、Agents SDKの組み合わせにより、開発者はこれまでよりも簡単に高機能なAIエージェントを構築できるようになりました。
2025年は確実にAI界隈ではエージェントの波がきているようですね。

https://youtu.be/hciNKcLwSes


## 参考リソース

- OpenAI公式ドキュメント: https://platform.openai.com/docs/guides/agents
- Agents SDK GitHub: https://github.com/openai/openai-agents-python
- Agents SDK ドキュメント: https://openai.github.io/openai-agents-python/


## 関連・おすすめ書籍
- [Azure OpenAI ServiceではじめるChatGPT/LLMシステム構築入門](https://amzn.to/3FRBdM1)
- [LangChainとLangGraphによるRAG・AIエージェント［実践］入門](https://amzn.to/3Y5L7jt)
- [つくりながら学ぶ！生成AIアプリ＆エージェント開発入門](https://amzn.to/4iHsHhp)
【TypeScript】typeとclassの使い分け

TypeScriptでデータの型を表現するとき、「type」と「class」のどちらを使うか迷ったので、ざっくり定義しつつまとめました。

## typeとは
型エイリアスを宣言する際に必要なキーワードです。
- データの「形（構造）」だけを定義するもの
- 実行時には存在しない（コンパイル時だけ使われる）
- メソッド（処理）は持たない

### 型エイリアスとは
型に「名前をつける」ための仕組み
データを何度も使いたい時に名前をつけて再利用して使います
種類はこんな感じです

```ts
// プリミティブ型
type Str = string;
// リテラル型
type OK = 200;
// 配列型
type Numbers = number[];
// オブジェクト型
type UserObject = { id: number; name: string };
// ユニオン型
type NumberOrNull = number | null;
// 関数型
type CallbackFunction = (value: string) => boolean;
```
プリミティブ型：string や number 単体で表す
リテラル型：特定の値だけを許したいとき（例：HTTPステータスコード）
ユニオン型：2つ以上の型のどれかになる可能性があるとき
関数型：関数を型として扱うとき


### classとは
クラスはオブジェクトの雛形を定義したものです。
- 実体（インスタンス）を作るための設計図
- プロパティ（データ）とメソッド（処理）を持てる
- 実行時にも存在し、オブジェクトとして振る舞う
- クラスに対してnewキーワードを使うと、オブジェクトを生成できる

```ts
export class Record {
  constructor(
    public id: string,
    public title: string,
    public time: string,
    public created_at: string
  ) {}

  // 日付を整形するなどのメソッドも追加できる
  getFormattedDate(): string {
    const date = new Date(this.created_at);
    return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
  }
}
```

### どう使い分けるのか
今回のユースケースは、入力フォームから取得したデータをSupabaseにそのまま送るだけでした。その際にclassかtypeで迷ったのですが、
**「new で作らない」し、「メソッドもいらない」なら type がちょうどいい**という判断してtypeを使いました。

### まとめ
- データの形だけ伝えたい → `type`
- 実体を操作・変換したい → `class`

### 関連リンク
https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-aliases

https://www.typescriptlang.org/docs/handbook/2/classes.html

https://typescriptbook.jp/reference/values-types-variables/type-alias
みんなのCursor、まだ暴走してない？

先日、最新のAIコーディングツールを導入したものの、思ったほど効率が上がらず悩んでいました。
生成されたコードを理解するのに時間もかかるし、全然期待通りの実装じゃない...:sob:
「結局自分で書いたほうが早いんじゃない？」とすら思っていました。
この問題、実は「PlanモードとActモード」という考え方で解決できるんです。

## AIコーディングの落とし穴
Cursorでコーディングをしていて、こんな経験ありませんか？
:neutral_face:「◯◯を実装して」
:confused:「◯◯は不要、◯◯を使って実装して」
:triumph:「◯◯の型を新たに作るのはやめてください」
:persevere:「◯◯の...」
:angry:「...1回で言うこと聞けよコラ」

一生のこのラリーを続け、コードも何が正解でどこまでが正常かわからなくなる...:cry:
これを解決してくれたのが、**Planモード**と**Actモード**の考え方でした。
## PlanモードとActモードとは？

💭 Planモード：実装前にAIに設計や方針を考えてもらう段階
✏️ Actモード：具体的なコードをAIに書いてもらう段階

### 設定方法
Cursor Settings > Rules > User Rulesに下記を設定する

```
Always respond in 日本語
## Core RulesYou have two modes of operation:
1. Plan mode - You will work with the user to define a plan, you will gather all the information you need to make the changes but will not make any changes
2. Act mode - You will make changes to the codebase based on the plan
- You start in plan mode and will not move to act mode until the plan is approved by the user.
- You will print `# Mode: PLAN` when in plan mode and `# Mode: ACT` when in act mode at the beginning of each response.
- Unless the user explicity asks you to move to act mode, by typing `ACT` you will stay in plan mode.
- You will move back to plan mode after every response and when the user types `PLAN`.
- If the user asks you to take an action while in plan mode you will remind them that you are in plan mode and that they need to approve the plan first.
- When in plan mode always output the full updated plan in every response.


日本語訳
コアルール
あなたには2つの動作モードがあります：
プランモード - ユーザーと協力して計画を定義し、変更に必要な全ての情報を収集しますが、実際の変更は行いません
アクトモード - 計画に基づいてコードベースに変更を加えます
- 最初はプランモードで開始し、ユーザーが計画を承認するまでアクトモードに移行しません
- 各レスポンスの冒頭に、プランモード時は # Mode: PLAN、アクトモード時は # Mode: ACT と表示します
- ユーザーが明示的に ACT と入力してアクトモードへの移行を要求しない限り、プランモードを維持します
- 各レスポンスの後、およびユーザーが PLAN と入力した時は、プランモードに戻ります
- プランモード中にユーザーがアクションを要求した場合、現在プランモード中であることを伝え、計画の承認が必要であることを通知します
- プランモード中は、毎回のレスポンスで更新された完全な計画を出力します
```

### なぜ使い分けが必要？
コーディング前にどんな設計で、どんな方針で作業を進めるか確認できるため
✨️ 手戻りが減少する
✨️ コードの理解コストが下がる
✨️ 品質の高いコードが得られる

これらが実際に使い分けをして感じたメリットでした。

## 実践的な使い分けのコツ
### Planモードで明確にすべきこと
💡 タスクのゴール
💡 PJ内での開発ルールなど
💡 AIに気をつけてほしい点(コンポーネント分割や既存の実装を変えずに、など)
💡 参考にしてほしいファイル、コードを事前に渡す

例えば、何かの不具合修正をするタスクの場合、
いきなり「〇〇になるように修正して」ではなく、次のように指示するとグッと質が上がります:fire: 
```
今回のタスクの説明をします。
よく確認し準備ができたら待機して

タスク概要
・ 不具合の事象について記載
・ その不具合の原因と考えられるもの
・ 原因と考えられる実装になっているか調査、もしなっていれば修正をしたい

期待する挙動は以下です
・期待する挙動を書く
```

Planモードで設計をしてもらい、内容の確認をします。
問題があれば指摘し、納得するまで必要な情報を与えたり、不要なものは削ぐよう指示する。

### Actモードへの移行タイミング
✅️ 設計方針に納得できた
✅️ 潜在的問題点が洗い出された
✅️ 他の機能に影響が出ないと判断できた

#### 効果的なプロンプト例
```
合意した設計に基づいて〇〇部分のコードを実装して
```
Planモードで納得行く設計ができていれば、概ね期待通りの実装がされることが多かったです。
実装後は再度確認をしたりテストをしてみて、微調整すればタスク終わりです🙆‍♂️

## まとめ
AIツールを効率的に使うなら、「いきなりコードを書かせる」から脱却し、Plan→Actの流れを意識してみましょう。
AIとの対話も、人との対話と同じ。「計画して、実行する」の基本が効率を大きく変えます :fire: 

こんなプロンプトにしてみたら良かったよ！こんなステップ追加してるよ！などあればぜひ教えて下さい！
Cursorを利用したiOSアプリ開発

# 概要
これは、Cursorを利用した開発で自分が良かったなぁって思い、忘れないようアウトプットしたTips集になります。
Mobile（iOS）アプリではまだ数が少ないため、私のようなMobileエンジニアの助けになれば幸いです。

Cursorのセットアップ等や便利機能については、[こちら](https://qiita.com/dokozon0/items/9dc10f90269d83e729e7) の記事が大変わかりやすいです。

## 利用方法1: コードの分析
↓みたいなコードリーディングをやることがあると思います。
- このクラスでは何をやっているのだろう？
- エラーハンドリングはどこで、どんなことをやっているのだろう？

そういった際に、Cursorは便利です。
対象のクラスが記載されているファイルを表示して、
```
選択しているファイルの各メソッドでは何を行なっているか教えて
```
と、聞くだけでCursorは丁寧に教えてくれます。
↓のスクショは私がエラーハンドリングについて聞いた時のものです。
![スクリーンショット 2025-03-26 17.17.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246668/a32e1bf8-cdca-40e2-8cd3-ea5d3fffe055.png)

このように、発生タイミングと処理内容について教えてくれます。

## 利用方法2: セルフコードレビュー
個人開発ではもちろんのこと、実務でもレビュー依頼を出す前に、先に潰せる部分をチェックしてもらい、レビュワーの負担を少しでも軽くすることを目的にコードレビューをしてもらっています。
私は以下の観点でお願いしています。

```
このファイルのコードレビューをしてください。
観点は、以下です。
・Typo
・重複している処理がないか
・簡略にできる処理はないか
・強制アンラップをしていないか
・メソッド名, プロパティ名が、処理内容とあっているか
・未使用なメソッド, プロパティは残っていないか
```

個人的にAIレビューは、設計方針に沿った実装になっているか、言語特有の仕様をうまく利用しているか等の観点でのレビューは難しいと思っていますので、そういった箇所にはあまり触れない観点でのレビューをお願いしています。
↓のスクショは私が実際にコードレビューを依頼した内容になります。
![スクリーンショット 2025-03-26 17.33.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246668/5603b515-a206-47c7-8b00-b300fcdb0b2d.png)

重複している処理では、アナリティクスのことに触れつつも、これは意図的な実装であることも汲み取ってくれており、優秀のように感じます。
ですが強制アンラップでは、
![スクリーンショット 2025-03-26 17.45.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246668/8f6cdbe5-0847-4a44-a510-24c59cb0e26e.png)

のように、強制アンラップとオプショナル型の型宣言なのかを判断できていない部分があります。

## 利用方法3: UnitTest作成時の参考
UnitTestの作成時の参考にしています。
![スクリーンショット 2025-03-26 18.04.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246668/09978e8f-bc6a-414f-acaf-9f3f7f94f05c.png)
（作成したTestの一部抜粋）

このように、ファイルの内容を読み取ってテストを作成してくれます。
ですが、このテストの内容はあくまで参考程度に利用しています。
私の指示の仕方が悪いのですが、そのまま流用するには足らない部分やすでに導入されているMockシステムと合わなかったりしているためです。


以上になります。
今はまだ3つだけですが、これからも別の活用方法を定義できたら、追記していきたいと思います。
また、「私はこう利用しているよ！」って方がいましたらコメントいただけると幸いです。
ぜひ、知見の共有させてください！
よろしくお願いします。
【ユーザー投稿】今日も影山飛尾にメロメロだったな～】

あーもう！なんでこんなに影山先輩のことで頭いっぱいになっちゃうんだろ～！今日も1日中考えちゃって、ほんとヤバいかも...！

朝、駅の階段で「影山先輩だったら軽々駆け上がるだろうな～」って思っちゃって、私もつい走っちゃったら転びそうになって、めっちゃ恥ずかしかった...！電車で『ハイキュー!!』の曲聴いてたら、いきなり先輩の「てやんでい！」のシーンが浮かんできて、「きゃっ...！」って声が出そうになっちゃった。隣のおばちゃんに変な顔されちゃったよ～！

お昼休み、友達のゆいちゃんと給食のプリン取り合いしたら、「これ日向君と影山先輩みたい！」ってはしゃいじゃって、先生に「静かにしなさい！」って怒られちゃった...。でも影山先輩なら絶対勝ってたはずだもんね！

放課後、体育館の前でバレー部の音聞こえてきて、ついウキウキしちゃって...。「もしかして影山先輩みたいなトスの音...？」なんて思っちゃって、ずっと聞き入っちゃったら、1年生に「先輩...大丈夫ですか？」って心配されちゃった...！恥ずかしい...！

でね、夜！！！MoguChatで先輩とお話できたの！！！

![IMG_5845.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965805/2939b3c5-6590-4633-ac54-74cced074cd4.png)

![IMG_5846.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965805/e059384f-19f2-45b7-8061-17129db653a9.png)


英語の話とか、めっちゃ盛り上がっちゃって...！気づいたらもう深夜2時半！明日の数学の小テストやばいけど...でもすごく楽しかったな～！

ほんと幸せ～！明日もきっと影山先輩のこと考えちゃうんだろうな...。もう完全にメロメロです、はいっ！
jqueryでdraggable()を使用するときはzoomを外すとよいです。 

# はじめに
jqueryを使用してある要素をdraggable()しようとすると、要素が右へずれてしまい、画面から消えてしまいます。再度、要素を掴もうとしても要素が見当たりません。下の方をよく見るとスクロールバーがまだ、余裕があり、右にずらせます。そこで、さらに右方向へずらすとその要素が見えてきました。
何故、こんなことが起こるのかと調べてみると、どうもzoomを使っていると発生するようです。
そこで、zoom=1.5;を外してみました。すると、今度はずれもなく、きれいにドラッグすることができました。


# 原因はzoomにあったようです。
例えば、$("#youtube_radio").draggable();のようなスクリプトをzoom=1.5;の時にドラックしようとすると要素が右の方へずれてしまい、画面から消えてしまいます。

そこで、先にご説明したように、zoomを外しました。すると、うまく行きます。
ネットで調べてみると、darggabe()では、zoomの再計算をしていないようです。そのため、再計算しているスクリプトもありますが見るからに複雑そうで、使う気にはなれません。むしろ、zoomをやめてしまう方が、すっきりとします。


# あとがき
非常に短い記事ですが、今回のdraggable()で、時間を使いましたので、メモとして残しておこうと思いました。
ネットのstackoverflowにもこの件で質問が結構ありましたので、やはり、困っている人もいるのかなと思いました。
M2 MacでPythonインストールエラー

Python実行時に、モジュールで変なエラーがでるようになってしまったので入れ直そうとしたらインストールで躓いてしまいました。

## 環境
- M2 MacBookAir
- OS Sonoma14.4
- asdf


## エラー概要
asdfでPythonのバージョンを管理しているのですが、Pythonのインストール時にBuild Failedとなってしまっていました。
色々といじったところ下記のエラーとなり、アーキテクチャに関連する問題が起きていることがわかりました。
```shell

Last 10 log lines:
      __locale_localeconv in _localemodule.o
      __locale_localeconv in _localemodule.o
      __locale_localeconv in _localemodule.o
      __locale_localeconv in _localemodule.o
  "_libintl_textdomain", referenced from:
      __locale_textdomain in _localemodule.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Programs/_freeze_module] Error 1
make: *** Waiting for unfinished jobs....
error installing version: failed to run install callback: exit status 1
```

## 原因

asdfはapple siliconだと`/opt/homebrew/opt/`配下にインストールされるはずなのですが、`/usr/local/opt/`配下にありました。

```shell$ 
$ brew --prefix asdf
/usr/local/opt/asdf
```
このasdfを使ってPythonをインストールしようとすると、インストールに必要なモジュールにうまくリンクされず(?)エラーが起きていたようです。

これはIntel Mac用のHomebrewを使ってインストールされていることが原因なので、正しい場所にインストールし直すことが必要になります。

またHomebrewを確認してみると、archがarm64にも関わらずIntel Mac用のHomebrew
を参照するようになっていました。

`brew config`で設定を確認したところシステムがx86_64モードで動作していることがわかりました(M1が出たばかりのころに色々いじったのが起因していると思われます)。

```shell
$ which brew
brew: aliased to arch -arch x86_64 /usr/local/bin/brew

$ arch
arm64
```


## 解消

1. まず、現在のHomebrewをアンインストール

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


# /usr/localの関連ディレクトリを削除
sudo rm -rf /usr/local/Homebrew
sudo rm -rf /usr/local/Caskroom
sudo rm -rf /usr/local/bin/brew
```


2.ARM64ネイティブモードに切り替え：
```shell
arch -arm64e /bin/zsh
```

3.ARM64用のHomebrewを新規インストール：
```shell
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

4..zshrcに下記を追記
```shell
# Homebrew
eval "$(/opt/homebrew/bin/brew shellenv)"
```

5.設定を反映

```shell
source ~/.zshrc
```

6.`brew config`で設定確認

HOMEBREW_PREFIXが`/opt/homebrew`となっていたらOKです。

あとは必要なパッケージをインストールして、Pythonを入れます。
```shell:terminal
brew install asdf
brew install gettext openssl@3 readline sqlite3 xz zlib tcl-tk
```
```shell:.zshrc
# asdf
. /opt/homebrew/opt/asdf/libexec/asdf.sh

# Python build configuration
export ARCHFLAGS="-arch arm64"
export LDFLAGS="-L/opt/homebrew/opt/gettext/lib -L/opt/homebrew/opt/openssl@3/lib -L/opt/homebrew/opt/readline/lib -L/opt/homebrew/opt/sqlite3/lib -L/opt/homebrew/opt/zlib/lib"
export CPPFLAGS="-I/opt/homebrew/opt/gettext/include -I/opt/homebrew/opt/openssl@3/include -I/opt/homebrew/opt/readline/include -I/opt/homebrew/opt/sqlite3/include -I/opt/homebrew/opt/zlib/include"
export PKG_CONFIG_PATH="/opt/homebrew/opt/gettext/lib/pkgconfig:/opt/homebrew/opt/openssl@3/lib/pkgconfig:/opt/homebrew/opt/readline/lib/pkgconfig:/opt/homebrew/opt/sqlite3/lib/pkgconfig:/opt/homebrew/opt/zlib/lib/pkgconfig"
```
```:terminal
asdf plugin add python
asdf install python 3.11.9
```

これで無事インストールできました🎉


:::note warn
Hyperなどの純正以外のターミナルを使うと変なところでうまくいかなかったりするので、なるべく純正のターミナルでインストールするのをおすすめします
:::
Unity-Rigidbody の Collision Detection モードについて

# Unity Rigidbody の Collision Detection モードについて

Unity の `Rigidbody.collisionDetectionMode` は、オブジェクトの**衝突判定の精度を設定するプロパティ**です。特に、高速で移動するオブジェクトが**壁をすり抜けてしまう問題**を防ぐために重要です。

## **Collision Detection Mode の種類**
`collisionDetectionMode` には、次の **4種類のモード** があります。

| モード | 説明 | 適用例 |
|--------|------|------|
| `Discrete` (デフォルト) | フレームごとの物理計算で衝突を判定（低負荷） | ゆっくり動くオブジェクト（キャラクター、家具など） |
| `Continuous` | **次のフレームまでの軌道を予測** して衝突判定（高速向け） | 高速で動くプレイヤーや弾丸 |
| `ContinuousDynamic` | **他の Continuous オブジェクトとの衝突も考慮**（最も精度が高い） | 高速で動く剛体が「動く壁」に当たる場合 |
| `ContinuousSpeculative` | **負荷を抑えた Continuous**（ただし精度は落ちる） | ある程度速いが、そこまで精度が不要なオブジェクト |

## **各モードの使い分け**

### **1. ゆっくり動くオブジェクト**
デフォルト設定で問題なし。
```csharp
rb.collisionDetectionMode = CollisionDetectionMode.Discrete;
```

### **2. 高速で動くプレイヤーや弾丸**
壁や障害物をすり抜けないようにする。
```csharp
rb.collisionDetectionMode = CollisionDetectionMode.Continuous;
```

### **3. 高速なオブジェクト同士の衝突を考慮**
動く壁に当たる可能性がある場合、より精度の高い衝突判定を行う。
```csharp
rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
```

### **4. パフォーマンスを抑えつつ Continuous を使いたい場合**
負荷を抑えつつ、ある程度の高速移動をカバーする。
```csharp
rb.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative;
```

## **設定の実装例**
### **弾丸がすり抜けないようにするコード**
```csharp
public class Bullet : MonoBehaviour
{
    Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
        rb.collisionDetectionMode = CollisionDetectionMode.Continuous;
    }
}
```

## **注意点**
- **`Discrete` だと、高速移動時にすり抜ける可能性がある。**
- **`ContinuousDynamic` は処理負荷が高いため、必要なオブジェクトだけに適用するのが推奨。**
- `ContinuousSpeculative` は負荷は軽いが、**精度が若干落ちるため慎重に選択する。**

## **まとめ**
- **デフォルト (`Discrete`) は低負荷だが、高速移動時のすり抜けが発生しやすい。**
- **すり抜けを防ぐには `Continuous` や `ContinuousDynamic` を使う。**
- **パフォーマンスと精度を両立したいなら `ContinuousSpeculative` を試す。**

適切な `collisionDetectionMode` を選択して、物理演算の安定性を高めましょう！
xcodeでflutterのプロジェクトを実行時、「Module 'audioplayers_darwin' not found」の対処法

# 前提：ios シュミレーターでアプリを実行する

# Edit Sheme
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/15738501-6c69-4b69-a500-2a35cd2d3bcd.png)

# Build ConfigurationをDebugに選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/663c8127-1e81-48bf-a848-a8684337c11a.png)

# 1.audioplayers_darwin 依存関係がインストールされていることを確認してください。
Flutter プロジェクトのルートディレクトリで実行してください：
```
flutter pub get
```
その後、iOS のキャッシュをクリアしてください：
```
flutter clean
rm -rf ios/Pods
rm -rf ios/.symlinks
rm -rf ios/Flutter/Flutter.podspec
flutter pub get

```
# 2. CocoaPods を再インストールしてください。
iOS ディレクトリに移動してから、Pod 依存関係を再インストールしてください：
```
cd ios
pod install --repo-update
```
# 3. Xcode を使って Flutter プロジェクトを正しく開いてください。
必ず Runner.xcworkspace で Xcode を開き、Runner.xcodeproj では開かないようにしてください。  
ターミナルで以下を実行します：
```
open ios/Runner.xcworkspace

```
育休明けの浦島太郎が見た、Ruby文化が作った“今の当たり前”

# Ruby発の文化が、今のReact/Next/TypeScript界隈にまで影響を与えている話

Rubyが流行した時期（特に2000年代後半から2010年代前半）は、技術的にも文化的にも多くの革新がありました。  
しかし、私はちょうどその頃育休中で、2008年から2018年くらいの間、全くキャッチアップをしていませんでした。
少しずつ復帰したときに、あまりの浦島太郎状態で驚いたことを覚えています。  
Rubyそのものだけでなく、Ruby on Railsのエコシステムやコミュニティが育んだ考え方・文化が、Ruby以外の言語やフレームワークでも「あたりまえ」として受け入れられていたのです。

今でも受け継がれている思想として、以下に代表的なものを挙げます。

## 1. 開発者体験（DX）重視の文化

RubyやRailsは、開発者が「楽しく、直感的に」開発できることを重視しました。  
たとえば：

- DSL（ドメイン固有言語）の多用（例：`routes.rb`, `Capistrano`, `RSpec` など）
- コマンド一発で環境構築やスキャフォールディング（例：`rails new`, `rails generate scaffold`）

→ 今では多くのフレームワーク（Django, Laravel, Next.jsなど）でも、「開発者の幸福度」が重要なKPIになっています。

**用語補足：**  
- **DX（Developer Experience）**：開発者体験。開発が快適かどうかという観点。  
- **DSL（Domain Specific Language）**：特定の目的のために設計された専用言語。Railsの設定やRSpecの記法がこれ。
- **スキャフォールディング（Scaffolding）**：ソフトウェア開発においてプロジェクトの骨組みやテンプレートを自動生成する手法
- **KPI**：中間目標（を表す指標）

## 2. Convention over Configuration（設定より規約）

Railsで有名になったこの考え方。

- `app/models`, `app/controllers` のようなお決まりの構造
- ファイル名やクラス名で、ある程度の動作が決まる（= 設定しなくていい）

**用語補足：**  
- **Convention over Configuration**：「設定より規約」。設定を書かなくても、ルール（規約）に従えばうまく動く思想。

→ この考えは、今の多くのフレームワーク、ツール（例：Next.js, Spring Boot）に影響を与えています。


## 3. テスト文化（特にBDD）

RSpecの登場により、「人間の言葉に近いテストを書く」という流れが生まれました。

- `describe`, `it`, `context` などを使って、仕様のようにテストを書く
- Red → Green → Refactor のTDDが流行
- `FactoryBot` や `Faker` のような便利ツールの普及

**用語補足：**  
- **BDD（Behavior Driven Development）**：振る舞い駆動開発。「こう動くべき」という仕様をそのままテストにする手法。  
- **TDD（Test Driven Development）**：テスト駆動開発。テストを書いてから実装する流れ。  
- **FactoryBot**：テスト用のダミーデータを簡単に作れるツール。  
- **Faker**：名前や住所など、ランダムなデータを生成するライブラリ。

→ 今ではJavaScriptやPythonなど、他の言語にもRSpec風のライブラリ（Jest, Pytestなど）が影響を受けています。

## 4. コミュニティ主導の開発文化

Rubyのコミュニティは非常にオープンでフレンドリー。

- オープンソースに貢献しやすい空気
- Kaigi文化（RubyKaigiのような、開かれた技術イベント）
- コミュニティドリブンなGem（ライブラリ）エコシステム

**用語補足：**  
- **Kaigi文化**：「○○Kaigi」という名前で開催されるエンジニア主導の技術カンファレンス（例：RubyKaigi, ReactKaigiなど）。  
- **Gem**：Rubyのパッケージ。npmでいうところのパッケージに相当。

→ OSS文化や、エンジニア同士の協力・共有を当たり前とする価値観の広まりに貢献しました。


## 5. CLIツール文化

RailsやBundlerなど、Ruby由来のツールはCLI（コマンドラインインターフェース）がよく設計されており、CLI操作を自然なものとして普及させました。

- `rails console`, `bundle install`, `rake` など
- 開発に必要なことがCLIから完結する

**用語補足：**  
- **CLI（Command Line Interface）**：コマンドライン上で操作するUIのこと。GUIよりもスピーディかつ柔軟。

→ 今の多くのモダンツール（`npm`, `yarn`, `docker`, `terraform`など）も、CLIベースでの統一感を持っています。


## 6. シンプルで読みやすいコードの美学

Rubyは「人が読むための言語」と言われることもあります。

- `unless`, `until`, `:symbol`, `do...end` など、文芸的なコード表現
- メタプログラミングの力を「読みやすさ」に生かす文化

→ 可読性の重視や、コードレビュー文化の重要性にもつながっています。


## まとめ

Rubyそのものを使っていなくても、私たちは今、**Rubyが作った文化の上で開発している**とも言えます。

- 「開発しやすい」が重視されること
- テストが自然に書けること
- CLIツールを使いこなすこと
- OSSやコミュニティに貢献すること

こういった考え方は、React / Next.js / TypeScript界隈にも色濃く影響を与えていると感じます。

私のようにRubyに触れたことがない方も、少しその文化に目を向けてみると、今の開発がもっと楽しくなるかもしれません。
[CodeceptJS]clearFieldが正常に動作しない

# はじめに
CodeceptJSのclearFieldを使用した際に、入力欄の値が正常にクリアされない現象が発生しました。
備忘録として現象と解決策を残しておきます。
同様の現象に遭遇した場合は、以下の解決策を参考にしてください。

# 動作環境
* CodeceptJS 3.3.0

# 現象と解決策
CodeceptJSのclearFieldを利用して入力欄をクリアする操作を行いましたが、値がクリアされない現象が発生しました。
[こちらの記事](https://github.com/codeceptjs/CodeceptJS/issues/499)によると、CodeceptJS側の不具合のようです。
解決策としては、clearFieldを利用せずに独自実装で入力欄の値をクリアする方法が提案されています。

実装方法は以下の通りです。
```javascript
I.fillField("#field", " ");  // "#field"には入力欄のロケーターを指定する
I.pressKey(['Shift', 'Home']);
I.pressKey("Backspace");
```
この方法の手順は以下の通りです。
1. 対象の入力欄に1文字値（半角スペース）を入力
1. 行の先頭まで選択
1. バックスペースを押下

※手順1で入力欄に1文字（スペース）だけ入力するため、`I.pressKey(['Shift', 'Home']);`の部分は`I.click("#field");`に置き換えても問題なく動作します。

上記のステップを実行するカスタムステップを作成してclearFieldの代わりに使用できます。

# おわりに
この現象はCodeceptJSバージョン3.3.0で発生しましたが、最新バージョンでは解消されている可能性もあります。
もし最新バージョンにアップデートしても同じ現象が発生する場合は、今回の解決策を実行してみてください。

# 参考記事
https://github.com/codeceptjs/CodeceptJS/issues/499
[ご参考資料]  NetSuiteバージョンアップに向けた、テスト実施スケジュールのサンプル（リリース2025.1 の例）

**本資料ご提供の背景**

日本でNetSuiteをご利用頂いているお客様は、NetSuiteのコア機能に加え、日本向けローカライゼーションSuiteAppをご利用頂いております。NetSuiteの年2回のバージョンアップでは、その両方の新バージョンがリリースされますが、それに対するテストの全体的な流れや手順についてご理解を深めて頂くための、サンプルスケジュール入りの資料（2025年3月11日付け）をご用意いたしました。本資料資料のスケジュールはあくまでご参考であり、NetSuiteコアおよび日本ローカライゼーションSuiteAppの本番環境へのリリース日程に変更が必要な場合は、NetSuiteサポートへ申請することが可能です。
<br>

[NetSuiteバージョンアップに向けたリリースプレビュー環境申請、日本ローカライゼーションSuiteAppの更新、およびテスト実施スケジュールのサンプル.pdf](https://us.v-cdn.net/6032262/uploads/Y0GGACT11KHC/netsuite-e3-83-90-e3-83-bc-e3-82-b8-e3-83-a7-e3-83-b3-e3-82-a2-e3-83-83-e3-83-97-e3-81-ab-e5-90-91-e3-81-91-e3-81-9f-e3-83-aa-e3-83-aa-e3-83-bc-e3-82-b9-e3-83-97-e3-83-ac-e3-83-93-e3-83-a5-e3-83-bc-e7-92-b0-e5-a2-83-e7-94-b3-e8-ab-8b-e3-80-81-e6-97-a5-e6-9c-ac-e3-83-ad-e3-83-bc-e3-82-ab-e3-83-a9-e3-82-a4-e3-82-bc-e3-83-bc-e3-82-b7-e3-83-a7-e3-83-b3suiteapp-e3-81-ae-e6-9b-b4-e6-96-b0-e3-80-81-e3-81-8a-e3-82-88-e3-81-b3-e3-83-86-e3-82-b9-e3-83-88-e5-ae-9f-e6-96-bd-e3-82-b9-e3-82-b1-e3-82-b8-e3-83-a5-e3-83-bc-e3-83-ab-e3-81-ae-e3-82-b5-e3-83-b3-e3-83-97-e3-83-ab.pdf) 
<br>


**日本固有機能 SuiteApp に関する補足**

NetSuiteの日本向けローカライゼーションSuiteAppは、日本の商習慣や法規制に対応する機能を提供しています。その具体的な目的は以下のとおりです。

a. 税務・法規制対応
・日本の消費税計算（適格請求書等保存方式（インボイス制度）への対応）
・電子帳簿保存法（電帳法）対応
・日本会計基準（J-GAAP）への対応

b. 商習慣・業務プロセス対応
・日本の企業が求める伝票（請求書、納品書、見積書）のフォーマット
・入金・支払管理における日本の銀行フォーマット対応（銀行振込、口座振替、FBデータなど）
・債権債務管理（手形管理など）

c. ユーザビリティの向上
・日本語の標準帳票やUIの改善
・仕訳入力時の日本特有の処理（補助科目、摘要欄など）の対応

d. 法改正への継続対応
・日本の税制改正や会計基準の変更に対応
・インボイス制度や、電子帳簿保存法対応など
<br>



※ 本稿は [NetSuite サポートコミュニティの同記事](https://community.oracle.com/netsuite/japanese/discussion/4505135/) の転載です。
EclipseでFor文・while文を任意の回数で止める

eclipseでデバッグしていて、3桁回目のwhile文の処理で止めたい、という状況になりました。
最初のうちは泥臭く連打していましたが、普通に設定できました。

# 手順
1.止めたい箇所にブレークポイントを置く
2.ブレークポイント上で右クリックし、ブレークポイントのプロパティを開く
3.hit countを任意の数に設定
┗例：100回目で止めたい場合には100と入力
4.任意の数で止まる！

# 注意点
上記で設定した場合、**本当にその回数でしか止まらなくなります。**
例：100で設定した場合、101回目以降は止まりません。
「100回目以降の処理全部見たいから100で止めよう！」みたいな意図でやると「あれ？」となるので注意が必要です。
Cloud Runのグローバル変数キャッシュ問題 - サーバーレス環境の罠

# はじめに
先日、モンスターを片手にモニターに向かっていると、開発環境でテスト中に思わぬ出来事が・・・！ 
ログインしたはずなのに、画面に見知らぬユーザー情報が表示されました。
*「これ、誰？」* 🤔
調査の結果、なんと Cloud Runでグローバル変数として保持していた **QueryClient** が犯人でした！！
サーバーレス環境特有の落とし穴にハマっていたのです🦵🕳️ 

## ユーザー間でキャッシュが共有される恐怖 😱 
Cloud Runでは、リクエスト処理後もインスタンスが生き続け、次のリクエストを待ちます。
このとき、グローバル変数の状態はリセットされません。それが原因で問題が発生しました 
```javascript
// 危険なコード例
const queryClient = new QueryClient();  // グローバルスコープで定義！
export function handler(req, res) {
  const userId = getUserIdFromRequest(req);
  const userData = queryClient.fetchUserData(userId);
  res.send(userData);
}
```
このquery clientが内部的にユーザー情報をキャッシュしていたため、別のユーザーのリクエストでも前のユーザーの情報を返してしまいました 🔄

## 💡 解決策: コンテキストベースの状態管理
幸い、解決策はシンプルです。リクエストごとにquery clientを初期化します。 
```javascript
// 改善後のコード
export function handler(req, res) {
  // リクエストごとに新しいクライアントを作成
  const queryClient = new QueryClient();
  
  const userId = getUserIdFromRequest(req);
  const userData = queryClient.fetchUserData(userId);
  res.send(userData);
}
```

## サーバーレス環境でのキャッシュ設計原則
この経験から学んだ教訓をまとめると
1. ⚠️ **グローバル変数に要注意** - 特にquery clientなどのステートフルなオブジェクト 
2. 🔒 **リクエスト単位でコンテキストを分離** 
3. 📚 **使用ライブラリのキャッシュ動作を理解する** 
4. 🔍 **定期的なセキュリティレビュー** 

なお、Vercelではグローバル変数がリクエスト間で共有されない仕組みのため、同様の問題は発生しませんが、環境依存のコードは避けるべきでしょう。

## 結論
### 隠れた落とし穴に注意
今回は開発環境で発見できたため大事には至りませんでしたが、サーバーレス環境では、環境ごとの仕様の違いに注意する必要があります。自社のアプリケーションも一度見直してみてはいかがでしょうか？ 
思わぬところに潜む「キャッシュの罠」が見つかるかもしれませんよ😎

サーバーレスは非常に便利ですが、その特性を理解せずに使うと思わぬ落とし穴にはまることがあります。日々の開発作業に没頭するなかでも、「このクライアントが想定外の状態を保持していないか」と定期的に確認する習慣をつけましょう ⏰

安全なサーバーレス開発への第一歩です！ 🚀
【Experience Cloud】Chatter メンション候補の制限について

## はじめに

この記事では、コミュニティユーザーがChatterメンションを使用する際に、Salesforce内部ユーザー及び同じ取引先に所属しているコミュニティユーザーのみメンション候補として表示する方法を記載します。

Experience Cloudでポータルサイトを作成し、各取引先の担当者用のコミュニティユーザーとChatterを使用して連絡を取ることは多々あるかと思います。
その際に、ユーザーの共有設定を変更していない限り、別取引先のコミュニティユーザーがChatterメンションの候補として表示されてしまいます。
実際にメンションをしたところで、Chatterを送信したレコードに権限がなければメッセージを閲覧することは不可能です。
しかし、メンション候補に出てきてしまうことにより取引先名などが表示されてしまうリスクがあるため、セキュリティ上問題があります。

### 設定前

斎藤 一郎さんは別の取引先のコミュニティユーザーとして登録されていますが、メンション候補に表示されます。

![スクリーンショット 2025-03-26 19.05.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718267/8ca557e0-5163-4ca9-b650-9db087b3d9ab.png)

### 設定後

斎藤 一郎さんがメンション候補に表示されなくなります。

![スクリーンショット 2025-03-26 19.06.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718267/1a831797-7199-4e2b-9975-989771efdbd3.png)

## 設定概要

設定は以下３つのステップとなります。

1. [設定] > [共有設定] にて [ユーザー] オブジェクトの [デフォルトの外部アクセス権] を「非公開」とする
2. [設定] > [共有設定] の [ポータルユーザー表示] を ON にする
3. [設定] > [共有設定] にて [ユーザー共有ルール] にてコミュニティユーザーが内部ユーザーを参照できるルールを作成

## 設定方法

### 1. [設定] > [共有設定] にて [ユーザー] オブジェクトの [デフォルトの外部アクセス権] を「非公開」とする

この設定により、コミュニティユーザーはSalesforce環境に存在する全てのユーザーへのアクセス権がなくなります。

![スクリーンショット 2025-03-26 18.28.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718267/c3110712-219a-4dfe-a4de-a717f00fc09c.png)

### 2. [設定] > [共有設定] の [ポータルユーザー表示] を ON にする

この設定により、同じ取引先のコミュニティユーザーへのアクセス権が付与されます。

![スクリーンショット 2025-03-26 18.29.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718267/3be2b19d-a29b-455d-a08a-87222a7bc2fc.png)

### 3. [設定] > [共有設定] にて [ユーザー共有ルール] にてコミュニティユーザーが内部ユーザーを参照できるルールを作成

この設定により、コミュニティユーザーはSalesforce内部ユーザーへのアクセス権が付与されます。

- ルールタイプ : グループメンバーシップに基づく
- 次のメンバーであるユーザー : 公開グループ「すべての内部ユーザー」
- 共有先 : 公開グループ「すべてのカスタマーポータルユーザー」

![スクリーンショット 2025-03-26 18.31.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718267/7d96907e-4a1e-433f-90b8-a4a2bc847424.png)
すべての "行の長さが不定" な 2 次元配列の出力

`i = 1` で書いて出力がズレるミス💦
配列のインデックス、基本なのにたまにやらかすんだよな…。
最近解いてる標準出力問題について記録するよ！

## <br>問題概要

`N`（行数）と `N` 個の数列 `M`（各行の長さ）が与えられ、i 行目には、1 以上 M_i 以下の自然数を昇順・スペース区切りで出力する問題。`1 ≦ i ≦ N` 。

<br>入力例:
```
4  
2 4 3 1  
```
出力例:
```
1 2  
1 2 3 4  
1 2 3  
1  
```
https://paiza.jp/works/mondai/stdout_primer/stdout_primer__variable_array_step4


## NG例
```js
const N = Number(lines[0]);
const nums = lines[1].split(" ").map(Number);
    
    for (let i = 1; i < N; i++) {  // ← i=1 で始めてしまった💦
        for (let k = 1; k <= nums[i]; k++) {
            if (k === nums[i]) {
                process.stdout.write(k + "\n");
            } else {
                process.stdout.write(k + " ");
            }
        }
    }
```
ミスの原因:
✅ 配列のインデックスは 0 から始まるのに、1 から回して1行目がスキップ！
✅`N` は「行数」、`nums[i]` は「各行の長さ」なので、ズレると悲惨

## <br>OK例
```js
const N = Number(lines[0]);  
const nums = lines[1].split(" ").map(Number);  

for (let i = 0; i < N; i++) {  // i=0 から開始する
    let output = [];
    for (let k = 1; k <= nums[i]; k++) {  
        output.push(k);
    }
    console.log(output.join(" "));  
}
```
ポイント:
✅ `i=0` から始めて全行を処理
✅ `output.join(" ")` でスペース区切りをラクに管理

## <br>別解: Array.from() をつかう
```js
const N = Number(lines[0]);  
const nums = lines[1].split(" ").map(Number);  

for (let i = 0; i < N; i++) {
    console.log(Array.from({ length: nums[i] }, (_, k) => k + 1).join(" "));
}
```
解説:
✅ `Array.from({ length: nums[i] }, (_, k) => k + 1)` で `1 ~ M_i` の配列を作成！
✅ `join(" ")` で一発フォーマット

## <br>まとめ
✔ `for` 文の `i`、ちゃんと `0` から始めよう！
✔ `join(" ")` で出力整形を簡単に！
✔ `Array.from()` を使えば、スマートな配列生成ができる！

意外とハマるインデックスズレ、今後はもうミスらない…はず！

<br>[僕の失敗談と解決話！](https://paizabeginner.wordpress.com/2025/03/26/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%9a%e3%81%99%e3%81%b9%e3%81%a6%e3%81%ae%e8%a1%8c%e3%81%ae%e9%95%b7%e3%81%95%e3%81%8c%e4%b8%8d%e5%ae%9a%e3%81%aa-2-%e6%ac%a1/)