OmniAICreator/Qiita-1.07M huggingface dataset:
Linux で Zed 使ってみた!!

## Linux で Zed 使ってみた!!

今までは MacOS 限定だった Zed エディターですが、ついに [Linux 版](https://github.com/zed-industries/zed/releases/tag/v0.143.6)もリリースされることになりました!!
ということで、今回は Linux で Zed を使う回です。

(https://github.com/zed-industries/zed/issues/7015)

### インストール

基本的にはこれが推奨されています:
```sh
curl https://zed.dev/install.sh | sh
```

プレビュー版 (stable よりも1週間早く機能が追加される) はこちら:
```sh
curl https://zed.dev/install.sh | ZED_CHANNEL=preview sh
```

[パッケージマネージャーを利用](https://zed.dev/docs/linux#installing-via-a-package-manager)することもできます。
(現状 apt では利用できませんが。)

詳細は https://zed.dev/docs/linux をご覧ください。

### 起動

```sh
zed
```
で起動できます。

アプリケーションのリストにも自動で登録されているので、GUI からの起動もできそうです!

### 実際に使ってみる

まずは起動から。
![Screenshot_20240711_225901.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2769460/046f7e68-b705-c10c-b4ba-dd0083451ffc.png)

ログインは GitHub との連携でできました。
![Screenshot_20240711_225918.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2769460/d524e23d-4062-2662-75ae-93fdaaf2bcfe.png)

右上の設定で VSCode で使っているテーマと同じテーマや、HTML の拡張機能などを入れてみました。

早速、この記事を Zed で書いてみることに。
![Screenshot_20240711_230639.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2769460/49a9b95e-f909-01f5-e0e2-22ea17926075.png)

左上の設定からフォントサイズを変更 (16px => 14px) して、いつも (VSCode) と同じ感じに。
コマンドパネル (<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd>) => `markdown: open preview` で Markdown のプレビューを表示しています。
![Screenshot_20240711_234358.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2769460/2ca8d5be-be87-9946-d2e8-72e89123929e.png)

### 使い勝手について

かなり安定していると感じました。
いつも使っていないエディターを使うのは新鮮で楽しいですね!!

#### 速度

Zed の特徴とも言える、起動速度に関してはそこそこ速いと感じました。
比較すると VSCode で3秒のものが Zed だと2秒くらいでした。劇的な変化…とは言い難いですが、度々ファイルを開く人にとってはよいかと思います。
あとは、起動以外の速度も向上していると思うので、気になるところですね。

#### AI

目玉機能ですが、未検証です…
Open AI の API キー持ってないんだよね。

#### 共同開発

こちらも目玉機能ですが、~~ともに使ってくれる友達がいないので、~~未検証です。

#### Git の履歴

Git を利用しているファイルでは、行に誰にいつ編集されたかが人目でわかる機能があります。
これは便利かも。

![Screenshot_20240711_234328.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2769460/ec8a4860-bf72-9ede-3bdd-34b1d580e9a7.png)

### 最後に

まだ開発途中というのもあり、機能や拡張機能の不足は感じますが、とても面白かったです。
自分の環境的に、Zed の目玉機能があまり使えていないのでなんとも評価できませんが、今後もたまに使ってみたいと思います。

今後開発が進歩して、より便利になることを期待しています。

<details>
<summary>余談</summary>
多分 Zed Linux についての日本語記事では Qiita 内初の記事?だと思う。
</details>
書式指定文字列の不思議な挙動

# これは何？

書式指定文字列に変なこと書いてもエラーにならない事に気づいて、色々試してみた記録

# 各種言語の対応

## go

この現象を発見したのは go。

```go:go
fmt.Printf("%d %+d %++d %+++d %++++d\n", 1, 1, 1, 1, 1)
//=> 1 +1 +1 +1 +1
 ```

二個以上書いても意味ないけど、エラーにならない。

`+` を書ける場所には ` ` も書けるが、意味的に共存できない。

戦わせると

```go:go
fmt.Printf("[%+d]\n", 1) // [+1]
fmt.Printf("[% d]\n", 1) // [ 1]
fmt.Printf("[%+ +d]\n", 1) // [+1]
fmt.Printf("[% + d]\n", 1) // [+1]
```

`+` が勝つ。

後勝ちだろうと予想していたので、予想が外れた。

## ruby

ruby も同様に `"%++++++++++++d" % 1` などはエラーにならない。

戦わせてみると

```ruby:ruby
"[+]%+d [ ]% d [+ +]%+ +d [ + ]% + d" % [1,1,1,1]
#=> "[+]+1 [ ] 1 [+ +]+1 [ + ]+1"
```

go と同じく `+` が強い。

## python3

python3 も同様に `"%++++++++++++d" % 1` などはエラーにならない。

戦わせてみると

```python3:python3
"[+]%+d [ ]% d [+ +]%+ +d [ + ]% + d" % (1,1,1,1)
#=> '[+]+1 [ ] 1 [+ +]+1 [ + ]+1'
```

こちらも `+` が強い。
 
## perl

```perl:perl
printf("[+]%+d [ ]% d [+ +]%+ +d [ + ]% + d", 1,1,1,1);'
#=> [+]+1 [ ] 1 [+ +]+1 [ + ]+1
```

こちらも `+` が強い。

こんなバグっぽい挙動でみんなの意見が揃うのが気持ち悪い。

## PHP

PHP は perl と同じ結果になりやすいという印象がある。

```PHP:PHP8.2.19
<?php
printf("[+]%+d [ ]% d [+ +]%+ +d [ + ]% + d", 1,1,1,1);
#=> [+]+1 [ ]1 [+ +]+1 [ + ]+1
```

やはり perl と同じで、つまり `+` が強い。


## C++

コンパイラによっては警告を出してくれた。

```c++:c++(clang18.1.0)
printf("[+]%+d [ ]% d [+ +]%+ +d [ + ]% + d", 1,1,1,1);
//=> warning: flag ' ' is ignored when flag '+' is present [-Wformat]
```

`'+'` があるんで `' '` は無視するよ、という警告で、`'+'` が二個あるよ、という警告ではない。

実際、 `%++d` や `%  d` などでは警告は出なかった。

clang と gcc と MSVC を試したけど、みんな go と同じく `+` が強く、`-` が弱い。

ここまで揃っていると仕様があるのかなと思ったりするけど調べてない。

 ## Java

 Java はエラーにしそうだなと予想していた。

```Java:Java
 System.out.printf("%++d", 1);
 //=> Exception in thread "main" java.util.DuplicateFormatFlagsException: Flags = '+'
```

やはりエラー。そういう人だよね。

## wsprintf (Windows)

MSDN には「もう使わないで」と書いてあるけど `wsprintf` は今でも使える。
この関数は

* 書き込まれるバッファは 1024 バイト固定
* `%f` がない

などの特徴がある気持ち悪い関数で、こいつなら他と違う挙動になるかと思ったんだけど、そもそも `+` などのフラグがなかった。残念。

`%##########x` や `%000000000d` のような無駄な指定がエラーにならないのは go などと同様だったんだけど、 ` ` と `+` のような戦いはできないのであった。


# まとめ

C 言語に由来すると思われる
　`"%d"`
のような書式文字列に
　`"++++++++++%d"`
のようなことを書いても意味がないわけだけど、 Java 以外はエラーにしない。

それと、この `+` と ` ` を戦わせると、みんな `+` の勝ちだった。不思議。
普通に書いたら後勝ちになりそうなものだと想像していたんだけれど。

思いつく限りの言語で試したんだけど、他に C の `printf` と同じような書式文字列が使える 言語 / ライブラリ ってなんかあったっけ。
type-challenges 中級編2: Deep Readonly,Tuple to Union,Chainable Options

# type-challenges 中級編2: Deep Readonly,Tuple to Union,Chainable Options

## はじめに type-challengesとは

[GitHubのtype-challengesリポジトリ](https://github.com/type-challenges)は、TypeScript型システムの理解を深めるための型クイズ問題集です。高品質な型を作成することで、バグを減らし、プロジェクトの保守性を向上させることができます。今回は中級編から3つの問題に挑戦します。

### 1. Deep Readonly

オブジェクトのすべてのパラメーター（およびそのサブオブジェクトを再帰的に）を読み取り専用にする `DeepReadonly<T>` を実装します。

この課題ではオブジェクトのみを扱っていると想定してください。配列、関数、クラスなどは考慮する必要はありません。

#### 例

```typescript
type X = { 
  x: { 
    a: 1
    b: 'hi'
  }
  y: 'hey'
}

type Expected = { 
  readonly x: { 
    readonly a: 1
    readonly b: 'hi'
  }
  readonly y: 'hey' 
}

type Todo = DeepReadonly<X> // should be same as `Expected`
```

#### 私の回答

```typescript
type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends Record<PropertyKey, unknown> ? DeepReadonly<T[K]> : T[K]
}
```

#### 解き方

- `readonly [K in keyof T]` というマッピング型を使い、型 `T` のプロパティ `K` を読み取り専用にします。
- `T[K]` がオブジェクト型の場合（`Record<PropertyKey, unknown>` で判定）、再帰的に `DeepReadonly` を適用します。
- オブジェクト型でない場合、そのプロパティの型をそのまま保持します。

:::note info
これはいつも通りの
```ts
{
  [K in keyof T]: T[K]
}
```
の拡張版ですね！応用を効かせれば解けます。
:::

### 2. Tuple to Union

タプルの値からユニオン型を生成する `TupleToUnion<T>` を実装します。

#### 例

```typescript
type Arr = ['1', '2', '3']

type Test = TupleToUnion<Arr> // expected to be '1' | '2' | '3'
```

#### 私の回答

```typescript
type TupleToUnion<T extends Array<unknown>> = T[number]
```

#### 解き方

- `T[number]` を使うことで、タプル `T` のすべての要素の型をユニオン型として取得できます。

:::note info
これも簡単！覚えておこう
:::

### 3. Chainable Options

`option(key, value)` と `get()` の2つの関数を提供する型 `Chainable<T>` を定義してください。`option` では、与えられたキーと値を使って現在の config の型を拡張できます。最終的な結果は `get` で取得することにしましょう。

#### 例

```typescript
declare const config: Chainable

const result = config
  .option('foo', 123)
  .option('name', 'type-challenges')
  .option('bar', { value: 'Hello World' })
  .get()

// expect the type of result to be:
interface Result {
  foo: number
  name: string
  bar: {
    value: string
  }
}
```

#### 私の回答

```typescript
type Chainable<T = {}> = {
  option<K extends string, V>(key: K, value: V): Chainable<T & Record<K, V>>
  get(): T
}
```

#### 解き方

- `option<K extends string, V>(key: K, value: V)` では、与えられたキー `K` と値 `V` を使って型 `T` を拡張します。
- 新しい `T` は `T & Record<K, V>` となり、これにより既存の型 `T` に新しいプロパティ `K` を追加します。
- `get` メソッドは、現在の `T` の型をそのまま返します。

:::note info
型の拡張を繰り返すことで、オプション設定をチェーンしていくことができます。
:::

### まとめ

このように、TypeScriptの型システムを理解し、実際に型を実装することで、より安全で保守性の高いコードを書くことができます。ぜひこれらの課題を解いて、型力UPしてみてください。

### 参考記事

- [TypeScript公式ドキュメント](https://www.typescriptlang.org/docs/)
- [type-challenges GitHubリポジトリ](https://github.com/type-challenges/type-challenges)
投稿 11 package .json 2024/07/11

本日の勉強時間　3H



`package.json` は、Node.js プロジェクトの基本情報や依存関係を管理するための設定ファイルです。このファイルにはプロジェクトに関するさまざまな情報が含まれています。以下は、`package.json` ファイルに含まれる主な内容です：

1. **name**: プロジェクトの名前。
2. **version**: プロジェクトのバージョン番号。
3. **description**: プロジェクトの簡単な説明。
4. **main**: プロジェクトのエントリーポイントとなるファイル。
5. **scripts**: プロジェクトで実行できるスクリプトの定義。例として、`start` や `test` などがあります。
6. **dependencies**: プロジェクトが依存するパッケージのリストとそのバージョン。
7. **devDependencies**: 開発時にのみ必要なパッケージのリストとそのバージョン。
8. **author**: プロジェクトの作者。
9. **license**: プロジェクトのライセンス情報。

`package.json` ファイルはプロジェクトのルートディレクトリに配置され、プロジェクトを他の開発者と共有する際や、CI/CD パイプラインでの依存関係のインストールに使用されます。以下に簡単な例を示します：

```json
{
  "name": "my-project",
  "version": "1.0.0",
  "description": "This is a sample project",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Your Name",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "nodemon": "^2.0.7"
  }
}
```

このファイルを使って、`npm install` コマンドで依存関係をインストールすることができます。
これからの情報伝達手段のあり方：空間コンピューティングを活用した革新的コミュニケーション

## 1. はじめに

現代において、情報伝達手段はメール、SMS、FAX、郵送、音声、SNSなど、多岐にわたります。しかし、これらの手段をより効果的に活用するためには、新しい技術の導入が不可欠です。今回は、Apple Vision Proのような空間コンピューティングを活用した新しい情報伝達手段のアイデアにを考案しました！

## 2. アイデアの概要

### 空間コンピューティングとは？

Apple Vision Proは、ユーザーが仮想空間と現実空間をシームレスに行き来できるデバイスです。この技術を活用することで、情報伝達手段を大幅に進化させることができます。

### 具体的な実装アイデア：パーソナライズされたバーチャルアシスタント

例えば、重要なメールやSNSの通知が届いた際に、ユーザーの視界に企業スタッフや相手のペルソナが現れ、「今少しお時間よろしいでしょうか？」と話しかけるシステムを導入します。このバーチャルアシスタントは、ユーザーの関心を引くために、自然な対話を通じてメッセージの内容を説明します。

## 3. 実装のメリット

1. **高いエンゲージメント率**
   バーチャルアシスタントが直接対話を通じて情報を伝えることで、ユーザーの関心を引き、メッセージの開封率や応答率が向上するはす。

2. **パーソナライズされた体験**
   ユーザーごとにカスタマイズされたペルソナが現れることで、よりパーソナライズされた体験が提供されます。これにより、ユーザーは情報をより理解しやすくなります。

3. **即時対応の促進**
   視覚的に目立つ通知や対話により、ユーザーは情報を即座に確認し、対応することが促進されます。これにより、重要な情報が見逃されるリスクが減少します。

4. **受動的な情報受信**
   スマホやPCでは、ユーザーが自分からアクションを起こさないとメッセージを確認できません。しかし、空間コンピューティングでは、相手側のペルソナからの会話が起点となるため、受け取ったユーザーが情報を確認する可能性が高まります。これにより、情報伝達の効率が向上します。

## 4. 実装のステップ

1. **ユーザーインターフェースの設計**
   バーチャルアシスタントがどのように現れ、どのように対話するかを設計します。AppleVisionProのペルソナ機能で自然な動きや表情を取り入れることで、ユーザーに親近感を与えます。空間ビデオも効果的です！

2. **コミュニケーションAPIの統合**
   メールやSNS、その他の情報伝達手段を統合し、バーチャルアシスタントがリアルタイムで情報を取得できるようにします。

3. **ユーザーのフィードバックの収集**
   実装後は、ユーザーからのフィードバックを収集し、改善を重ねていきます。これにより、ユーザー体験を最適化します。

## 5. アイデアの選出基準

1. **新規性と革新性**
   このアイデアは、空間コンピューティングを活用することで、従来の情報伝達手段に新しい価値を付加します。

2. **広く参考になる可能性**
   多くの企業やサービスに応用できるため、情報伝達手段の進化に大きく貢献する可能性があります。

3. **ユーザーへのメリット**
   ユーザーは、より直感的でパーソナライズされた情報伝達手段を享受できるため、満足度が向上します。（きっと！）

## 6. おわりに

Apple Vision Proのような空間コンピューティングを活用した情報伝達手段は、これからの時代におけるコミュニケーションの新たなスタンダードとなると革新しています！
今すぐに実現出来るかは難しいかもしれませんが、AppleVisionProを使った感じだと、そう遠くない未来に実現可能だと確信しています！
SwiftUI学びの備忘（DispatchQueue.main.async）

Swift学習中。GoogleMapのAPIを使うアプリを作りたくて、ひとまず書籍に載ってるWebAPIとJsonを学ぼうと思ったが、うまく行かない部分があり、chatGPTに聞いて解決したことを備忘。

JSONデータのダウンロードまでは無事できたが、必要な項目が配列に入らない。たぶんここが問題だろうと思い、chatGPTに質問。

~~~swift.swift
 for item in items {
                if let name = item.name
                   {
                    let list = ListItem(name: name)
                    DispatchQueue.main.async{
                        self.List.append(list)
                    }
                }
            }            
            print(self.List)
~~~

print(self.okashi)の出力結果が[]のまま

GPTの回答
print部分にDispatchQueueを追加

~~~swift.swift
for item in items {
                if let name = item.name
                {
                    let list = ListItem(name: name)
                    DispatchQueue.main.async {
                        self.List.append(list)
                    }
                }
            }
            DispatchQueue.main.async {
                print(self.List)
            }
~~~

ひとまず、これで無事に配列に追加されました！

自作アプリ作成までまだ道は遠い
Qiitaにあってほしい機能

## はじめに
Qiitaを使っていて、この機能があればなと思うことがありました。
実際に、同じ考えの人もいるかもしれないので挙げてみたいと思います。

## ジャンル関係なくすべての投稿のいいね順で検索できない
Qiitaでは検索したものに関してはいいね順に並べ替えることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/d96e2370-9992-1704-cf56-2f103026adcb.png)

ただ、すべての記事の中でのいいね順はできないと思います。（私が知らないだけかも）
今までのQiitaの歴史でどの記事がいいね最も多かったのか検索出来たらいいなと思いました。
もしくは、**歴代いいね順**みたいなリンクがQiitaのサイトにあればいいなと。

https://qiita.com/newbee1939/items/48a37fcdc458603797de

一応いいねランキングという記事は見つけました。100位以下もいい記事がありそうなので知りたいです。

## タグ一覧のリンクが見当たらない
どんなタグがあるのか知りたいなと思ったとき、見当たらず検索したらありました。

https://qiita.com/tags

便利なので、わかりやすいところにリンク置いてほしいです！

## 記事数が多い人の最初の記事をすぐに見ることができない
記事数が数百越えのユーザーの最初の記事を見たいと思っても、1ページ1ページクリックしないといけません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/a38216ce-10c9-5327-fa95-0f2c9c53d8e7.png)

**最初と最後のページネーションのボタンはつけてほしい！**

ただ、これは裏技があってクエリパラメータをいじればいいです。
`https://qiita.com/shinry?page=2`
`page=`の数字の部分をいじって検索すれば好きな場所に飛べます。
このあたり、もしかしてQiitaのエンジニアが私たちユーザーを試しているのでしょうか？
**ユーザーをふるいにかけているのではないか**
**厳選したユーザーのみしか残らないようにしているのか**

## フォルダごとに記事を分けられない
私のこだわりかもしれないですが、マイページの記事をジャンルごとにわけたいです。
技術系、体験談系、知識系等でジャンル分けして表示したいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/18a72474-8e72-24ca-ddbf-03f2a2384e21.png)

自分で見返すときも、このジャンルの記事書いたんだと見返しやすいし、見る人も読みたい記事を見つけやすくなると思います。

## 終わりに
もしかしたら、今あげたものを実現する裏技があるのかもしれないですが、見つけられなかったです。
もし、まだない機能でしたらQiitaのエンジニアの方！
<font color="#ff9933">**実装の検討お願いします！**</font>
【Flutter】ListView.Builder内のonTapイベントが勝手に呼ばれて困った話

## 何が起きたか
タイトルのままですが。

詳細は省きますが、ListViewの中に動的に画像を表示し、その画像をタップするとカルーセル表示する・・・みたいな処理を実装していました。Twitter（現X）とかでありそうなやつです。

```dart
class SampleListBuilder extends StatelessWidget {
  const SampleListBuilder({super.key});

  @override
  Widget build(BuildContext context) {
    final List<String> imageUrlList = ['url1', 'url2', 'url3'];

    return ListView.builder(
      physics: const AlwaysScrollableScrollPhysics(),
      itemCount: imageUrlList.length,
      itemBuilder: (BuildContext context, int index) {
        return Container(
          child: InkWell(
            onTap: _pushCarousel(index),
            child: Image.network(imageUrlList[index], fit: BoxFit.cover,),
          ),
        );
      },
    );
  }

  pushCarousel(context) {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => CarouselView()),
    );
  }
}
```

ビルドすると以下のエラーが発生します。

```
'!_debugLocked': is not true.
```

## 調査
調べてみると、Widgetのビルド中に画面遷移を行おうとしたりすると発生するエラーとのこと。
全く自覚なし。だってタップしたときのイベントで設定しているんだから。（つもり）

イベントの処理を変えてテストしてみます。

```dart
...省略
        return Container(
          child: InkWell(
            onTap: test(index), // テスト用メソッドに変更
            child: Image.network(imageUrlList[index], fit: BoxFit.cover,),
...省略

  test(index) {
    debugPrint('on tap! ' + index.toString());
  }
}
```

これで一応ビルドは出来るようになりましたが、ビルドしただけなのにコンソールにタップされたよ！のログが並びます。

## 解決
結論、書き方が悪かったです。
`onTap: メソッド(),`だとメソッドの戻り値をonTapイベントにセットするような動きをするのだそうです。

```dart
onTap: () => test(index),
```

とするのが正解でした。

または、画面遷移したいのであればちゃんとメソッドに型を指定すれば"void型は設定できないよ"と教えてくれるので気づけたかもしれません。
うーん、不幸が重なった感じ・・・
調べても全然出てこなかったのはあまりに常識的過ぎてこんなミスをする人がいなかったからなのでしょうか。
誰かの助けになれば幸いです。

### 修正後サンプル
```dart
class SampleListBuilder extends StatelessWidget {
  const SampleListBuilder({super.key});

  @override
  Widget build(BuildContext context) {
    final List<String> imageUrlList = ['url1', 'url2', 'url3'];

    return ListView.builder(
      physics: const AlwaysScrollableScrollPhysics(),
      itemCount: imageUrlList.length,
      itemBuilder: (BuildContext context, int index) {
        return Container(
          child: InkWell(
            // ①ラムダ式を使う
            onTap: () => _pushCarousel(index),
            child: Image.network(imageUrlList[index], fit: BoxFit.cover,),
          ),
        );
      },
    );
  }

  // ②返却型は書いたほうが自分のためになる
  void pushCarousel(context) {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => CarouselView()),
    );
  }
}
```
【基本編】Goのインターフェースについてざっくり

## インターフェースとは？

インターフェースは、メソッドの集合を定義するための型です。インターフェースを実装するためには、そのインターフェースが定義するすべてのメソッドを持つ必要があります。

### インターフェースの定義

以下は、インターフェースの基本的な定義方法です：
```go:例
type Speaker interface {
    Speak() string
}
```

この例では、`Speaker`というインターフェースを定義し、`Speak`というメソッドを持っています。

### インターフェースの実装

インターフェースを実装するためには、そのインターフェースが定義するメソッドを持つ型を作成します。
```go:例
type Person struct {
Name string
}
func (p Person) Speak() string {
return "Hello, my name is " + p.Name
}
```

この例では、`Person`という構造体が`Speaker`インターフェースを実装しています。

## `interface{}`型とは？

`interface{}`型は、Go言語における特別なインターフェースで、空のインターフェースとも呼ばれます。`interface{}`は、すべての型を受け入れることができるため、汎用的なデータ型として使用されます。

### `interface{}`の使用例

以下は、`interface{}`を使用した例です：
```go:例
func PrintValue(v interface{}) {
    fmt.Println(v)
}
```

この例では、`PrintValue`関数が`interface{}`型の引数を受け取り、どのような型の値でも受け入れることができます。

### 型アサーション

`interface{}`型の値を具体的な型に変換するためには、型アサーションを使用します。
```go:例
func PrintValue(v interface{}) {
    if str, ok := v.(string); ok {
        fmt.Println("String value:", str)
    } else {
        fmt.Println("Unknown type")
    }
}
```

この例では、`v`が`string`型であるかどうかをチェックし、`string`型であればその値を出力します。

## まとめ

Go言語のインターフェースは、メソッドの集合を定義するための強力な型です。インターフェースを使用することで、異なる型に共通の動作を持たせることができます。また、`interface{}`型は、すべての型を受け入れる汎用的なデータ型として非常に便利です。
【Pybulletサンプル解説】SAT（衝突検出アルゴリズム）を有効化【satCollision.py】

Pybullet公式gitリポジトリのサンプルコードを解説するシリーズです（一覧は[こちら](https://qiita.com/akinami/items/7b433b60aeb5115ba4d7)）。

<br>

今回は、satCollision.pyを解説します。（コードのリンクは[こちら](https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/satCollision.py)）

本コードを実行すると、SAT（衝突検出アルゴリズム）の有効化された状態で、オブジェクトが生成されます。

※ SAT(Separating Axis Theorem)は複雑な形状の衝突を検出するのに向いている衝突検出アルゴリズムです。

![satCollision.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/8f1c2788-c58d-9a13-365b-63a60cf83ac6.gif)


# 使用している機能
本コードは、以下の機能を使用すると「SAT（衝突検出アルゴリズム）の有効化」ができます。



## SAT（衝突検出アルゴリズム）の有効化
`setPhysicsEngineParameter` 関数を使用することで、物理エンジンに関するパラメータを設定できます。

```python
pybullet.setPhysicsEngineParameter(enableSAT)
```
- `enableSAT`：SAT（衝突検出アルゴリズム）を有効化するか（`0` or `1`）

# コメントをつけたサンプルコード
サンプルコードにコメントをつけたものが以下になります（もともとあった不要と思われるコメント等については削除しています）

```python
import pybullet as p
import time
import pybullet_data

# PybulletをGUIモードで接続
p.connect(p.GUI)

# Pybulletに関するデータパスを取得
p.setAdditionalSearchPath(pybullet_data.getDataPath())

# 重力を設定
p.setGravity(0, 0, -10)

# SAT機能を有効化
p.setPhysicsEngineParameter(enableSAT=1)

# キューブのオブジェクトを生成
p.loadURDF("cube_concave.urdf", [0, 0, -25],
           globalScaling=50,
           useFixedBase=True,
           flags=p.URDF_INITIALIZE_SAT_FEATURES)

# 床のオブジェクトを生成
p.loadURDF("cube.urdf", [0, 0, 1], globalScaling=1, flags=p.URDF_INITIALIZE_SAT_FEATURES)

# アヒルのオブジェクトを生成
p.loadURDF("duck_vhacd.urdf", [1, 0, 1], globalScaling=1, flags=p.URDF_INITIALIZE_SAT_FEATURES)

# Pybulletが起動している間、ループを繰り返す
while (p.isConnected()):

  # シミュレーションを1時刻分進める
  p.stepSimulation()

  # 衝突点情報を取得
  pts = p.getContactPoints()

  time.sleep(1. / 240.)
```
Difyの知識

Difyは簡単にRAGを使った生成AIが作れる仕組みです。

## RAGについて

https://qiita.com/momomoge/items/d119ebd3db9c600b8af9

RAGとは、簡単に外部データをLLMに渡すことができます。

以下のような外部データも連携をすることができます。

- Notion
- Firecrawlを使ってホームページの情報を取得する

### 参考サイト

https://qiita.com/minorun365/items/4c5dba1de7977c386249
クラウド環境でのリソース利用状況を監視するベストプラクティス


## はじめに
クラウド環境でのプロダクト開発が一般的になり、リソースの利用状況を適切に監視することがますます重要になっています。リソースの過剰利用や不足は、コストの増加やパフォーマンスの低下を引き起こす可能性があります。この記事では、クラウドベンダーの提供する様々なサービスを活用し、リソースの利用状況を効果的に監視する方法について解説します。

## 1. リソース監視の重要性
リソース監視は、システムの健全性を保つための基本的な活動です。適切な監視を行うことで、以下のようなメリットがあります。

- **コスト管理**: 不要なリソースの削減や、適切なスケーリングによるコスト最適化。
- **パフォーマンス向上**: リソース不足によるパフォーマンス低下を防止。
- **障害予防**: 異常なリソース使用を早期に検知し、障害を未然に防ぐ。

## 2. クラウドベンダーの監視サービス
主要なクラウドベンダー（AWS、Azure、GCP）は、それぞれ強力な監視サービスを提供しています。以下に代表的なサービスを紹介します。

### AWS CloudWatch
AWS CloudWatchは、AWSリソースの監視と管理を行うためのサービスです。メトリクスの収集、ログの監視、アラームの設定などが可能です。

### Azure Monitor
Azure Monitorは、Azureリソースの監視と分析を行うためのサービスです。メトリクスとログの収集、アラートの設定、ダッシュボードの作成が可能です。

### Google Cloud Monitoring
Google Cloud Monitoringは、GCPリソースの監視と管理を行うためのサービスです。メトリクスの収集、アラートの設定、ダッシュボードの作成が可能です。

## 3. 監視のベストプラクティス
リソース監視を効果的に行うためのベストプラクティスをいくつか紹介します。

### メトリクスの選定
監視するメトリクスを適切に選定することが重要です。CPU使用率、メモリ使用量、ディスクI/O、ネットワークトラフィックなど、システムの健全性を示す主要なメトリクスを監視対象としましょう。

### アラートの設定
異常を早期に検知するために、適切なアラートを設定します。例えば、CPU使用率が80%を超えた場合にアラートを発生させるなど、具体的な閾値を設定します。

### ダッシュボードの作成
リアルタイムでリソースの利用状況を把握するために、ダッシュボードを作成します。主要なメトリクスを一目で確認できるように配置し、異常が発生した際に迅速に対応できるようにします。

### ログの監視
メトリクスだけでなく、ログも重要な情報源です。エラーログやアクセスログを監視し、異常な動作やパターンを検出します。

## 4. 自動化の活用
監視作業を効率化するために、自動化を活用します。例えば、インフラストラクチャー・アズ・コード（IaC）ツールを使用して、監視設定をコード化し、再利用可能な形で管理します。

## まとめ
クラウド環境でのリソース利用状況の監視は、システムの健全性を保つために欠かせない活動です。主要なクラウドベンダーの提供する監視サービスを活用し、適切なメトリクスの選定、アラートの設定、ダッシュボードの作成、ログの監視、自動化の活用を行うことで、効果的なリソース監視を実現しましょう。

皆さんのプロダクト開発がよりスムーズに進むことを願っています。この記事が少しでもお役に立てれば幸いです。
LeetCode挑戦日記：Day34

# はじめに

最近、業務で実装する時間よりも資料作成やレビューをする時間が多くなってきました。
このままでは自身のコーディング能力が落ちそうで怖いので、LeetCodeを始めてみました。

自身の学習の記録 & LeetCodeに興味のある人が挑戦しやすいように、記事に残していきます。
このような競技プログラミングをした経験がないので、ひよってEasyからやっていきます...

# [Easy] 872. Leaf-Similar Trees

二分木のすべての葉を左から右の順に考えると、それらの葉の値が葉の値のシーケンスを形成します。

```plantuml
(3) -- (5)
(3) -- (1)
(5) -- (6)
(5) -- (2)
(1) -- (9)
(1) -- (8)
(2) -- (7)
(2) -- (4)
```

例えば、上記の与えられた木では、葉の値のシーケンスは (6, 7, 4, 9, 8) です。
2つの二分木は、葉の値のシーケンスが同じであれば葉相似と見なされます。
根ノードがroot1とroot2である2つの木が葉相似である場合に限り、trueを返します。

## 素直に解いてみる

### 考え方

1. `root1`と`root2`のシーケンスをそれぞれ求める
1. 各シーケンスを前から比較する

### コーディング

```typescript
function leafSimilar(root1: TreeNode | null, root2: TreeNode | null): boolean {
    const getSequence = (root: TreeNode | null): number[] => {
        if (!root) { return []; }
        if ((!root.left) && (!root.right)) { return [root.val]; }
        return getSequence(root.left).concat(getSequence(root.right));
    }

    const sequence1 = getSequence(root1);
    const sequence2 = getSequence(root2);
    if (sequence1.length !== sequence2.length) { return false; }

    for (let i = 0; i < sequence1.length; i++) {
        if (sequence1[i] !== sequence2[i]) {
            return false;
        }
    }
    return true;
};
```

### 結果

Runtime：57ms
Beats 85.20%

Memory：52.18MB
Beats 60.62%
Linter と Formatter について

みなさんは、Linter や Formatter を使用していますか

Pythonの開発では、Linterとして flake8、Formatter として Black などがよく使用される(体感です)と思います。

これらについて考える機会や知る機会が意外となく、実務経験では必須レベルなのに知らない方も多そうなので軽く調査したことを書いていきます。

## 本記事のまとめ
Lint や Formatter をCI/CDに組み込むと幸せになれます！！！



## そもそも Lint, Format is 何？

結論から言うと、自動でコードがベストプラクティスに従ってるか、解析してくれるものです。

例えば、Python では [PEP8](https://peps.python.org/pep-0008/)と呼ばれる、コードを書く際の決まりがあります。
コードは動かすだけなら簡単にかけますが、個々人が好き勝手にいろんな書き方をしてしまうと他の人の書いたコードが読みづらかったりして、今後の開発に差し支えてしまいます。

そこで、コードを書く際のルールを決めたものが PEP8 です。


[Lint](https://en.wikipedia.org/wiki/Lint_%28software%29) は、このようなコードの規則やベストプラクティスに従っていないコードを[静的解析](https://ja.wikipedia.org/wiki/%E9%9D%99%E7%9A%84%E3%82%B3%E3%83%BC%E3%83%89%E8%A7%A3%E6%9E%90)によってチェックします。

[Formatter](https://e-words.jp/w/%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%82%BF%E3%83%BC.html#:~:text=%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%82%BF%E3%83%BC%EF%BC%88formatter%EF%BC%89%E3%81%A8%E3%81%AF%E3%80%81,%E5%88%86%E9%87%8E%E3%82%84%E5%AF%BE%E8%B1%A1%E3%81%AB%E3%82%88%E3%81%A3%E3%81%A6%E7%95%B0%E3%81%AA%E3%82%8B%E3%80%82)は、コードに影響が出ない範囲内で、軽微な修正をするようにコードを静的解析でチェックします。

(静的解析とは、ざっくりコードを実行せずに解析することをいいます。)

静的開発ツールであり、ファイルを読み込んでルールベースに合致するか判定するだけなので色々と開発でされてます。
Python では Linter として、Flake8、Formatter として Black, isort などをよく使います。(他のツールもよく使います。)


## どう使うの？

ここでは Python で flake8, black を使用してみます。
パッケージ管理ツールとして poetry を使用してますが、pip などでも同じです。
- flake8
```
poetry add flake8
```
- black
```
poetry add black
```

下記コマンド実行すると、警告が表示されたりフォーマットが修正されたりしていい感じにしてくれます。(細かい使い方は公式ドキュメントをご参照ください)
```
poetry run flake8 .
poetry run black .
```

かなり簡単に使えますね！！！

## なんでつかうの？どこに使うの？

既に説明しましたが、基本的に多人数でのgitなどの環境での開発で使われます。
そのため、いわゆるCI/CD(Continuous Integration/Continuous Delivery & Deployment)にてアプリケーションのデプロイの自動化でチェックする際に使われます。

例えば、Github Actions と呼ばれる CI/CD ツールでは、以下のような yml ファイルを .github/workflows/の配下におくことで、push や pull request を行う際に、black や flake8 が自動で行われます。
```
name: CI

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:

  check-lint-and-formatting:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: 3.10
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install poetry
        poetry install --no-root
    - name: Format with Black
      run: poetry run black --check .
    - name: Lint with flake8
      run: poetry run flake8 .
```

## まとめ
意外と知らないLinterやFormmaterについて書いてみました。

何か間違いや気になることがあれば気軽にご連絡いただけますと幸いです。
【Pybulletサンプル解説】オブジェクトのテクスチャのIDを取得【getTextureUid.py】

お疲れ様です。秋並です。

Pybullet公式gitリポジトリのサンプルコードを解説するシリーズです（一覧は[こちら](https://qiita.com/akinami/items/7b433b60aeb5115ba4d7)）。

<br>

今回は、getTextureUid.pyを解説します。（コードのリンクは[こちら](https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/getTextureUid.py)）

本コードを実行すると、

![getTextureUid.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/60ae7aaf-e431-41c3-ec96-edf469dde5f2.gif)


# 使用している機能
本コードは、以下の機能を使用して「指定したオブジェクトのテクスチャのIDの取得」を実現しています。

## 指定したオブジェクトのテクスチャのIDの取得
`getVisualShapeData` 関数を使用することで、指定したオブジェクトの視覚情報を取得できます。

```python
visualData = pybullet.getVisualShapeData(objectId, p.VISUAL_SHAPE_DATA_TEXTURE_UNIQUE_IDS)
```
- `visualData`：オブジェクトの視覚情報
- `objectId`：オブジェクトのID
- `VISUAL_SHAPE_DATA_TEXTURE_UNIQUE_IDS`：テクスチャのIDも取得するフラグ

<br>

上記の「視覚情報`visualDara`」の[0][8]を指定すると、オブジェクトのテクスチャのIDを取得できます。
```python
textureId = visualData[0][8]
```

# コメントをつけたサンプルコード
サンプルコードにコメントをつけたものが以下になります（もともとあった不要と思われるコメント等については削除しています）

```python
import pybullet as p
import pybullet_data

# PybulletをGUIモードで接続
p.connect(p.GUI)

# Pybulletに関するデータパスを取得
p.setAdditionalSearchPath(pybullet_data.getDataPath())

# 床のオブジェクトを生成
plane = p.loadURDF("plane.urdf")

# 床のオブジェクトの視覚情報を取得
visualData = p.getVisualShapeData(plane, p.VISUAL_SHAPE_DATA_TEXTURE_UNIQUE_IDS)
print(visualData)

# 床のオブジェクトのテクスチャのIDを取得
curTexUid = visualData[0][8]
print(curTexUid)

# pngファイルからテクスチャのIDを取得
texUid = p.loadTexture("tex256.png")
print("texUid=", texUid)

# 床のオブジェクトにpngファイルから取得したテクスチャを適用
p.changeVisualShape(plane, -1, textureUniqueId=texUid)

# カメラ画像を取得
for i in range(100):
  p.getCameraImage(320, 200)

# 床のオブジェクトをもとのテクスチャに戻す
p.changeVisualShape(plane, -1, textureUniqueId=curTexUid)

# カメラ画像を取得
for i in range(100):
  p.getCameraImage(320, 200)
```
AWS LambdaでmsoffcryptoライブラリOS依存エラー対応

- 参照：https://qiita.com/yomon8/items/d4e5d8e6b536d490681f

- 言語：`Python3.11`

Windows環境で`msoffcrypto-tool`のzipを作成して、layerに設定して使ったら、参照のqiita記事と同じく下記のようなエラーが発生していた。
```
lib64/libc.so.6: version `GLIBC_2.28' not found
```

OS依存関係の問題がある模様だった。
ChatGPTに聞いたらDockerを使ってみてと言うが、その方法も上手くいかない。

それで参照のqiita記事を読んでヒントを得て下記のようにlayer用のzipを作成してみた。

- 修正前
```
pip install msoffcrypto-tool -t ./python/
```

- 修正後
```
pip install --platform manylinux2014_x86_64 --implementation cp --only-binary=:all: msoffcrypto-tool -t ./python/
```

（以降`/python`を圧縮）

これで作ったzipをlayerに設定したら、
`GLIBC_2.28`関連エラーがなくなって正常に動くようになった。

因みにExcelファイルにパスワードをかけるために`msoffcrypto-tool`を使った。
【Pybulletサンプル解説】オブジェクトの重心位置を変更する【shiftCenterOfMass.py】

Pybullet公式gitリポジトリのサンプルコードを解説するシリーズです（一覧は[こちら](https://qiita.com/akinami/items/7b433b60aeb5115ba4d7)）。

<br>

今回は、shiftCenterOfMass.pyを解説します。（コードのリンクは[こちら](https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/shiftCenterOfMass.py)）

本コードを実行すると「重心位置を変更したオブジェクト」が生成されます。

![shiftCenterOfMass.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/3c47058f-3075-53af-24c8-c56efeeeb6e1.gif)


# 使用している機能
本コードは、以下の機能を使用して「指定した視覚形状、衝突形状のオブジェクトを生成」することができます。

## 指定した視覚形状、衝突形状のオブジェクトを生成
`createMultiBody` 関数を使用することで、指定した視覚形状、衝突形状のオブジェクトを生成できます。

```python
pybullet.createMultiBody(baseMass,
                  baseInertialFramePosition,
                  baseCollisionShapeIndex,
                  baseVisualShapeIndex,
                  basePosition,
                  useMaximalCoordinates)
```
- `baseMass`：質量
- `baseInertialFramePosition`：慣性位置のオフセット
- `baseCollisionShapeIndex`：衝突形状のインデックス
- `baseVisualShapeIndex`：視覚形状のインデックス
- `basePosition`：初期位置
- `useMaximalCoordinates`：最大座標系を使用するかどうか

<br>

今回の場合、`baseInertialFramePosition`を `[0,0,-0.5]`に設定しているため、重心が中心から-0.5の位置に移動しています。


# コメントをつけたサンプルコード
サンプルコードにコメントをつけたものが以下になります（もともとあった不要と思われるコメント等については削除しています）

```python
import pybullet as p
import time
import pybullet_data

# PybulletをGUIモードで接続
p.connect(p.GUI)

# Pybulletに関するデータパスを取得
p.setAdditionalSearchPath(pybullet_data.getDataPath())

# 床のオブジェクトを生成
p.loadURDF("plane.urdf")

# 重力を設定
p.setGravity(0, 0, -10)

# 視覚形状の原点位置
visualShift = [0, 0, 0]

# 衝突形状の原点位置
collisionShift = [0, 0, 0]

# 慣性の原点位置（重心位置）
inertiaShift = [0, 0, -0.5]

# メッシュのスケール
meshScale = [1, 1, 1]

# 視覚形状の設定
visualShapeId = p.createVisualShape(shapeType=p.GEOM_MESH,
                                    fileName="cube.obj",
                                    rgbaColor=[1, 1, 1, 1],
                                    specularColor=[0.4, .4, 0],
                                    visualFramePosition=visualShift,
                                    meshScale=meshScale)

# 衝突形状の設定
collisionShapeId = p.createCollisionShape(shapeType=p.GEOM_MESH,
                                          fileName="cube.obj",
                                          collisionFramePosition=collisionShift,
                                          meshScale=meshScale)

# 指定した視覚形状、衝突形状のオブジェクトを生成
p.createMultiBody(baseMass=1,
                  baseInertialFramePosition=inertiaShift,
                  baseCollisionShapeIndex=collisionShapeId,
                  baseVisualShapeIndex=visualShapeId,
                  basePosition=[0, 0, 1],
                  useMaximalCoordinates=False)

while (1):
  
  # シミュレーションを1時刻分進める
  p.stepSimulation()
  time.sleep(1. / 240.)
```
FlutterでAndroidのビルドが失敗する

少し手間取ったので忘備録として記載します。

## 現象
AndroidStdioをアップデート
いつものようにAndroidエミュレータを選択してビルドするとエラーが起きた
```
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:compileFlutterBuildDebug'.
> A problem occurred starting process 'command '/Users/{userName}/fvm/versions/3.16.0/bin/flutter''

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 2s
Exception: Gradle task assembleDebug failed with exit code 1
```
この後、--verboseで詳細のログを確認するとなんだかGradleが原因っぽい失敗の仕方をしていた。
そこを重点的に右往左往したが、
下記のstackOverFlowに辿り着いた。
https://stackoverflow.com/questions/60386994/gradle-build-failing-after-update/64054311#64054311

一見関係なさそうな感じではあるが、gradleデーモンを止めたところで再度、ビルドで立ち上がるので一度、止めてみた。
```
cd cd android

./gradlew --stop 
Stopping Daemon(s)
2 Daemons stopped
```
2つ消えた？
と思い再度、ビルドすると無事に通った

恐らく元々、動いていたデーモンが生きていてアップデートを行なってさらにデーモンが起動してしまったと推察している。
2つ起動しているため、キャッシュの整合性やリソース競合などが起こって正常にビルドができなかったのかも知れない。

ちなみにこの後、ビルドして再度デーモンを止めると今度は1つかないので、2つはやはり異常な状態であったと思う。
Azure Container Appsの内部構造を暴きたかった

# はじめに
以前4回に分けてDockerとAzure Kubernetes Serviceのネットワークの内部構造を色々と調査しました。

https://qiita.com/maplejava/items/a70ef1a4e62b73085aa1

https://qiita.com/maplejava/items/a821fca27aa2e9e5d94e

https://qiita.com/maplejava/items/7c207e9192d811d5e194

https://qiita.com/maplejava/items/5ac616809e385841b973

今度はAzure Container Apps（以下、ACA）のネットワーク構造について紐解いてみたくなりました。以下では、ACAの内部構造を暴くために検証してみた結果を書いていきます。

# ACAとは

- 2022年5月にGAした、**コンテナベースのアプリケーション**を簡単にデプロイ、管理、スケールできるサービス
- フルマネージドk8sベースのアプリケーションプラットフォーム
- k8sが提供する高い可用性、セキュリティ、スケーラビリティの恩恵を受けつつ、**k8sの管理は不要**
- KEDA、Dapr、EnvoyといったCNCFプロジェクトの成果物をマネージドサービスとして提供する
- 内部的には**Azure Kubernetes Service (AKS)** を使用している

※AKSについては以前の記事を参照。

https://qiita.com/maplejava/items/f5e9ce8ba21afeb02d4b

### AKSとの違い
AKS：k8sAPI使いたい、k8sの設定自由度を確保したいならAKSを使うべき。
ACA：k8sAPIは意識しない。k8sの機能は使いたいけどクラスターの管理とかはしたくない人向けの便利なプラットフォーム。

なので、k8sが提供する高い可用性、セキュリティ、スケーラビリティの恩恵を受けたいがk8sの管理が大変、そもそもk8sを勉強するのが難しい、k8s開発スピード早すぎてついていけないという人にACAがおすすめ。

参考

https://learn.microsoft.com/ja-jp/azure/container-apps/compare-options

# やってみたこと
## VMSSへのSSHログイン
### 想定
ACAを構成するAKSクラスター内のVMSSにログインできれば内部構造が鮮明になるのではないか。
### 結果
- VMSSへのnmapコマンド実行（ポートスキャン）
→SSHは空いていた。　「22/tcp open ssh」

- VMSSへのSSHログイン
→右記メッセージが出て、ログインできなかった。　 「 Permission denied (publickey).」

## 内部向けLBへのTraceroute
### 想定
ホップアドレスとしてACAを構成するAKS内のPod等のIPアドレスが確認できるのではないか。
### 結果
コマンドの結果からは送信元の検証用VMと内部向けLB（10.33.0.62）が直接通信しているように見えた。
SDNの世界でルーティングされているため、このような結果となったと推測している。
```
TRACEROUTE (using port 80/tcp)
HOP RTT     ADDRESS
1.00 ms 10.33.0.62
Nmap done: 1 IP address (1 host up) scanned in 0.23 seconds
```
## ACAにおけるコンテナ間通信のTraceroute
### 想定
2つのコンテナが内部的には異なるVMSSにて起動している場合、AKSでTracerouteすると以下のような流れになる。

送信元PodのIPアドレス→送信元NodeのIPアドレス→送信先NodeのIPアドレス→送信先PodのIPアドレス

ACAは内部的にAKSを使用しているので、ACAでも同様の結果となるはずである。

### 検証環境　
送信元PodのIPアドレス：10.33.0.61
送信元NodeのIPアドレス：10.33.0.33
送信先NodeのIPアドレス：10.33.0.4
送信先PodのIPアドレス：10.33.0.21

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/c5f58398-acc8-10ce-cb06-f3d0a676d709.png)


### 結果
コマンドの結果から、想定は正しいと考えている。

```
sh-5.1# traceroute 10.33.0.21
traceroute to 10.33.0.21 (10.33.0.21), 30 hops max, 60 byte packets
 1  10-33-0-33.npm-metrics-cluster-service.kube-system.svc.cluster.local (10.33.0.33)  0.058 ms  0.015 ms  0.010 ms
 2  10-33-0-4.npm-metrics-cluster-service.kube-system.svc.cluster.local (10.33.0.4)  0.853 ms  0.784 ms  0.843 ms
 3  10-33-0-21.azfooaca-aca01-2--7b6u83h-headless.k8se-apps.svc.cluster.local (10.33.0.21)  0.923 ms  0.894 ms  0.878 ms
```


なお「npm-metrics-cluster-service.kube-system.svc.cluster.local」については以下の通り。

- kube-system：AKSに既定で作成される名前空間名
- npm-metrics-cluster-service：Prometheusの設定で、クラスターレベルのメトリクスを集めるために使用されるサービス。AKSクラスター上のkube-system名前空間内に存在している


# おわりに
上記に加えて、3回に分けてACAの選択できるネットワークオプションごとにネットワーク構造を整理した記事もありますので、是非見てみて下さい！

https://qiita.com/maplejava/items/e2ba406af12a018f03d8

https://qiita.com/maplejava/items/62517f945fe34c3cea96

https://qiita.com/maplejava/items/90b81237c721192b563b
Github・Git入門

## 概要
- [友人向けパート2](https://qiita.com/koinunopochi/items/fde6cee0373da0094447)
- GitHubにあるリポジトリをローカル環境にクローンし、新しいブランチを作成して変更をプッシュするまでの一連の流れを説明します。

## 1. リポジトリのクローン

まず、`git clone`コマンドを使ってGitHubリポジトリをローカル環境にクローンします。

```
git clone https://github.com/koinunopochi/Hello-World
cd .\Hello-World\
```

## 2. 新しいブランチの作成と切り替え

次に、`git checkout -b`コマンドを使って新しいブランチ（test-branch）を作成し、そのブランチに切り替えます。

```
git checkout -b test-branch
git branch

git checkout -b next-delete-branch
git branch
git branch -d next-delete-branch
```

## 3. ファイルの追加や変更

新しいファイル（git-test.md）を作成します。

```
echo >> "git-test.md"
```

## 4. 変更のステージングとコミット

`git status`コマンドで現在の状態を確認し、`git add`コマンドで変更をステージングエリアに追加します。

```
git status
git add .\git-test.md
git commit -m "test"
```

## 5. リモートリポジトリへのプッシュ

最後に、`git push --set-upstream origin test-branch`コマンドを使って、新しいブランチとその変更をリモートリポジトリ（origin）にプッシュします。

```
git push --set-upstream origin test-branch
```

## 最後に
マージなどに関しては、GitHub上で行います

https://github.com/koinunopochi/Hello-World

に関しては好きに触ってもらって大丈夫なので、常識の範囲内でPRなど出してもらって大丈夫です！
【Java】繰り返し処理のwhile文

## はじめに
Javaの学習中にwhile文を使って繰り返し処理を行おうとしたのですが、上手く結果が出力されませんでした。
調べた際に、単純にwhileの条件式に対する認識が間違っていたので記録しておきます。

## 条件式
whileを使う条件式は以下の通りです。
```java:text
while (trueになる条件を入れる){
  // 実行される処理…()の部分がfalseになったら終了
:
}
```

```java
while(true) {
    // 実行される処理…無限ループでbreak;を設定して終了させる
:
    if(条件式) {
        break;
    }
}
```

## 間違えていた内容
以下が間違えていた記述です。

```diff_java:
package ex;

public class ex_13 {

	public static void main(String[] args) {
		// 3でも7でも割り切れる数字を10個出力
  
		int count = 0;
		int num = 1;
		int sum = 0;
-		while(count == 10) {
+		while(count < 10) {
			if(num % 7 == 0 && num % 3 == 0) {
				System.out.print(num + " ");
				sum += num;
				count ++;
			}
			num ++;
		}
		System.out.println("\n10個の数字の合計値：" + sum);

	}

}
```
while ()内に入れた条件式が「trueになるまで実行される」と勘違いしていました。
実際は、条件式が「trueになっている間に実行される」ということでした。

試しにwhile文の中に
「System.out.println(count);」
などを入れて実行してみるとcountが表示されなかったので、while文の中身が反映されていないということは分かったのですが、どうしても原因が分からずにwhileの使い方を改めて調べてみることにしました。

https://www.javadrive.jp/start/for/index6.html

>while (条件式){
>  // 繰り返しの中で実行される処理
>  ...
>}

>繰り返し処理は条件式を評価して true だった場合には { から } のブロック内に記述された処理を上から順番に実行し、 false だった場合には繰り返し処理を終了し while 文の次へ処理を映します。

while文の使い方を調べたら、原因はすぐに分かりました。
初期設定を「int count = 0;」にしたにもかかわらず「while(count == 10)」を当てはめたので最初からfalseになってwhile文を通らなかったのでした…。


ちなみに、無限ループを実行したいときはwhile(true) にすることで常にtrueの状態にすることが出来ます。
その際は、最後にif文で終了させる際の条件式を追加するとwhileを抜けることが出来ます。

```diff_java
package ex;

public class ex_13a {

	public static void main(String[] args) {
		// 3でも7でも割り切れる数字を10個出力
		int count = 0;
		int num = 1;
		int sum = 0;
+		while(true) {
-		while(count < 10) {
			if(num % 7 == 0 && num % 3 == 0) {
				System.out.print(num + " ");
				sum += num;
				count ++;
			}
			num ++;
			
+			if(count == 10) {
+				break;
+			}
		}
		System.out.println("\n10個の数字の合計値：" + sum);

	}

}
```


私は、この「条件式を設定する場合」と「trueで無限ループを行う場合」がごちゃ混ぜになって勘違いしてしまっていました。

## おわりに

最近はなるべく調べずに、どこが間違っているか自分の頭で考えるということを意識しています。
そうなると、今回のようにそもそもの使い方が間違っていたということにも遭遇するのですが、すぐに検索していたころよりも知識として身につきやすくなった気がします。

最終的には検索しましたが、今回はwhile文の使い方が怪しいと踏んでいたためピンポイントで調べて答えにたどり着くことが出来ました。

これも、AIなどを使わずに、しっかりと仮説を立ててから実行する訓練だと思って取り組んでいこうと思います。
Dockerコマンド一覧

# Dockerコマンド一覧
Dockerは、アプリケーションのコンテナ化を支援するための強力なツールです。以下に、Dockerの主要なコマンドとその説明をまとめました。これらのコマンドを活用して、Dockerの基本的な操作を効率的に行えるようになります。


# Dockerコマンドの基本操作
イメージ関連のコマンド
イメージの取得
Docker Hubからイメージを取得します。

```bash
docker pull イメージ名
```

## イメージの一覧表示
ローカルに存在するイメージを一覧表示します。

```bash
docker images
```
## イメージの削除
不要なイメージを削除します。

```bash
docker rmi イメージ名
```

## イメージのビルド
Dockerfileを使用してカスタムイメージをビルドします。

```bash
docker build -t イメージ名 .
```

# コンテナ関連のコマンド
### コンテナの起動
イメージから新しいコンテナを作成し、起動します。

```bash
docker run --name コンテナ名 -d -p ホストポート:コンテナポート イメージ名
```

## コンテナの一覧表示
起動中のコンテナを一覧表示します。

```bash
docker ps
```
すべてのコンテナ（停止中のものも含む）を表示します。

```bash
docker ps -a
```
## コンテナの停止
起動中のコンテナを停止します。

```bash
docker stop コンテナ名
```

## コンテナの再起動
停止中のコンテナを再起動します。

```bash
docker start コンテナ名
```

## コンテナの削除
停止中のコンテナを削除します。

```bash
docker rm コンテナ名
```

# ネットワーク関連のコマンド
ネットワークの一覧表示
Dockerネットワークの一覧を表示します。

```bash
docker network ls
```
## 新しいネットワークの作成
カスタムDockerネットワークを作成します。

```bash
docker network create ネットワーク名
```

## コンテナをネットワークに接続
既存のコンテナを特定のネットワークに接続します。

```bash
docker network connect ネットワーク名 コンテナ名
```

## ネットワークからコンテナを切断
コンテナを特定のネットワークから切断します。

```bash
docker network disconnect ネットワーク名 コンテナ名
```

# ボリューム関連のコマンド
ボリュームの一覧表示
Dockerボリュームの一覧を表示します。

```bash
docker volume ls
```
## 新しいボリュームの作成
カスタムDockerボリュームを作成します。

```bash
docker volume create ボリューム名
```

## ボリュームの削除
不要なボリュームを削除します。

```bash
docker volume rm ボリューム名
```

# その他の便利なコマンド
ログの確認
コンテナのログを表示します。

```bash
docker logs コンテナ名
```

## コンテナに接続してシェルを起動
コンテナ内でシェルを起動します。

```bash
docker exec -it コンテナ名 /bin/bash
```

## Dockerイメージのプッシュ
ローカルのDockerイメージをDocker Hubにプッシュします。

```bash
docker push ユーザー名/イメージ名
```

## Dockerイメージのタグ付け
Dockerイメージにタグを付けます。

```bash
docker tag イメージ名 ユーザー名/リポジトリ名:タグ
```

# 【まとめ】
Dockerの基本的なコマンドを使用することで、コンテナの管理やイメージの操作を効率的に行うことができます。

# 【参考】
https://kinsta.com/jp/blog/docker-commands/
HashiCorp VaultでCubbyholeを使ってより安全にキーを取得する

# 概要

HashiCorp Vaultは、高度なセキュリティとアクセス制御を提供するシークレット管理ツールです。
Vaultには、より高いセキュリティを提供するCubbyholeというシークレット管理の仕組みがあります。本記事では、Cubbyholeを使用してシークレットを安全に取得する方法について解説します。

# Cubbyholeとは？

CubbyholeはVaultのセキュリティ機能で、特定のトークンに紐付けられたシークレットを隔離して保存します。
このトークンが失効すると、関連するシークレットも自動的にアクセス不可になります。他のトークンやrootユーザーでもアクセスできないため、高いセキュリティが実現されます。

# Cubbyholeを使ったシークレットの取得

以下に、Cubbyholeを使用してシークレットを安全に取得する手順を示します。

## 1. シークレットの保存

まず、シークレットをkey/valueシークレットエンジンに保存します。以下のコマンドを使用して、シークレットを保存します。

```bash
[~]$ vault kv put secret/dev username="webapp" password="my-long-password"
= Secret Path =
secret/data/dev

======= Metadata =======
Key                Value
---                -----
created_time       2024-07-10T12:40:31.114905Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1
```

## 2. シークレットの取得とラッピング

次に、シークレットを取得し、ラッピングトークンを生成します。ラッピングトークンは、一時的なトークンであり、指定したTTL（Time To Live）内でのみ有効です。

```bash
[~]$ vault kv get -wrap-ttl=120 secret/dev
Key                              Value
---                              -----
wrapping_token:                  hvs.CAESIK4hYBMievDjDUfriXLUWYwNVjv-ZZWAJ7QIP_vs2_GbGh4KHGh2cy52TTk1SUhYVlEwblIxMW9TNnBlSGlrZlY
wrapping_accessor:               v2mIsiC5DS1HudMBtvzCyniC
wrapping_token_ttl:              2m
wrapping_token_creation_time:    2024-07-10 21:40:53.106739 +0900 JST
wrapping_token_creation_path:    secret/data/dev
```

上記のコマンドは、120秒間有効なラッピングトークンを生成します。

## 3. ラッピングトークンの展開

ラッピングトークンを使用して、シークレットを取得します。まず、環境変数にラッピングトークンを設定します。

```bash
[~]$ export WRAPPING_TOKEN="hvs.CAESIK4hYBMievDjDUfriXLUWYwNVjv-ZZWAJ7QIP_vs2_GbGh4KHGh2cy52TTk1SUhYVlEwblIxMW9TNnBlSGlrZlY"
```

次に、`vault unwrap`コマンドを使用して、シークレットを取得します。

```bash
[~]$ VAULT_TOKEN=$WRAPPING_TOKEN vault unwrap
Key         Value
---         -----
data        map[password:my-long-password username:webapp]
metadata    map[created_time:2024-07-10T12:40:31.114905Z custom_metadata:<nil> deletion_time: destroyed:false version:1]
```

# まとめ

Cubbyholeを使用することで、シークレットをより安全に管理できます。ラッピングトークンは一時的なトークンであり、期限が切れるとアクセスできなくなるため、セキュリティが強化されます。
type-challenges 中級編1: Get Return Type, Omit, Readonly 2

# type-challenges 中級編1: Get Return Type, Omit, Readonly 2

## はじめに type-challengesとは

[GitHubのtype-challengesリポジトリ](https://github.com/type-challenges)は、TypeScript型システムの理解を深めるための型クイズ問題集です。高品質な型を作成することで、バグを減らし、プロジェクトの保守性を向上させることができます。今回は中級編から3つの問題に挑戦します。

### 1. Get Return Type

組み込みの型ユーティリティ `ReturnType<T>` を使用せず、関数 `T` の戻り値の型を取得する型を実装します。

#### 例

```typescript
const fn = (v: boolean) => {
  if (v)
    return 1
  else
    return 2
}

type a = MyReturnType<typeof fn> // expected to be 1 | 2
```

#### 私の回答

```typescript
type MyReturnType<T> = T extends (...args: infer X) => infer R ? R : never
```

#### 解き方

- `T extends (...args: infer X) => infer R` という条件型を使い、関数 `T` の戻り値の型 `R` を推定します。
- 関数である `T` の戻り値型が `R` として推定される場合、その型 `R` を返します。
- そうでない場合は `never` を返します。

:::note info
inferの使い方さえわかれば簡単。
:::


### 2. Omit

組み込みの型ユーティリティ `Omit<T, K>` を使用せず、型 `T` からプロパティ `K` を削除する型を実装します。

#### 例

```typescript
interface Todo {
  title: string
  description: string
  completed: boolean
}

type TodoPreview = MyOmit<Todo, 'description' | 'title'>

const todo: TodoPreview = {
  completed: false,
}
```

この問題は答えを見ちゃいました。

```typescript
type MyOmit<T, K extends keyof T> = { [P in keyof T as P extends K ? never : P]: T[P] }
```



#### 解き方

- `P in keyof T as P extends K ? never : P` というマッピング型を使い、型 `T` のプロパティ `P` が `K` に含まれている場合は `never` を返し、それ以外の場合はそのプロパティの型をそのまま保持します。
- 結果的に、指定されたプロパティ `K` が削除された新しい型が作成されます。

:::note info
as句でこんな書き方ができるんですね、、
:::
### 3. Readonly 2

2つの型引数 `T` と `K` を取る `MyReadonly2<T, K>` を実装します。`K` が指定されている場合は、`T` の中の `K` のプロパティのみを読み取り専用にします。`K` が指定されていない場合は、通常の `Readonly<T>` と同様に、すべてのプロパティを読み取り専用にします。

#### 例

```typescript
interface Todo {
  title: string
  description: string
  completed: boolean
}

const todo: MyReadonly2<Todo, 'title' | 'description'> = {
  title: "Hey",
  description: "foobar",
  completed: false,
}

todo.title = "Hello" // Error: cannot reassign a readonly property
todo.description = "barFoo" // Error: cannot reassign a readonly property
todo.completed = true // OK
```

#### 私の回答

```typescript
type MyReadonly2<T, K extends keyof T = keyof T> = {
  readonly [P in K]: T[P]
} & {
  [P in Exclude<keyof T, K>]: T[P]
}
```

#### 解き方

- `readonly [P in K]: T[P]` というマッピング型を使い、`T` の中で `K` に含まれるプロパティを読み取り専用にします。
- `Exclude<keyof T, K>` を使い、`K` に含まれないプロパティをそのまま保持します。
- これを & 演算子で結合し、必要なプロパティのみを読み取り専用にします。

:::note info
これは綺麗に解けた！気持ちが良い！！！！
`K extends keyof T = keyof T`でデフォルト型を入れられるのも便利。実務で役立てていきたい！
:::

### まとめ

このように、TypeScriptの型システムを理解し、実際に型を実装することで、より安全で保守性の高いコードを書くことができます。ぜひこれらの課題を解いて、型力UPしてみてください。

### 参考記事

- [TypeScript公式ドキュメント](https://www.typescriptlang.org/docs/)
- [type-challenges GitHubリポジトリ](https://github.com/type-challenges/type-challenges)
AtCoder 勉強記録[C++] その17

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## C - HonestOrUnkind2
[C - HonestOrUnkind2](https://atcoder.jp/contests/abc147/tasks/abc147_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n, xx, yy;
  cin >> n;
  vec a(n);
  vector<vector<ll>> x(n,vector<ll>(0));
  vector<vector<ll>> y(n,vector<ll>(0));
  for(int i = 0; i < n; i++){
    cin >> a[i];
    for(int j = 0; j < a[i]; j++){
      cin >> xx >> yy;
      x[i].push_back(xx);
      y[i].push_back(yy);
    }
  }
  ll res = 0;
  for(int bit = 0; bit < (1 << n); bit++){
    bool jud = true;
    vec hone(n, 0);
    ll tmp = 0;
    for(int i = 0; i < n; i++){
      if(bit&(1<<i)) {
        hone[i] = 1;
        tmp++;
      }
    }
    for(int i = 0; i < n; i++){
      for(int j = 0; j < a[i]; j++){
        if(!hone[i]) continue;
        if(hone[x[i][j]-1] != y[i][j]) jud = false;
      }
    }
    if(jud) res = max(tmp, res);
  }
  cout << res << endl;
}
```
### 解法
1から`N`までの人の中で誰が正直者かでbit全探索を行う。要素が`N`の配列を用意しておき正直者の番号を記憶しておく。その後証言と照らし合わせて矛盾しない場合の最大値を出力する。
## C - One-stroke Path
[C - One-stroke Path](https://atcoder.jp/contests/abc054/tasks/abc054_c)
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
bool g[10][10];

int main() {
  ll a, b, n, m;
  cin >> n >> m;
  for(int i = 0; i < m; i++) {
    cin >> a >> b;
    a--, b--;
    g[a][b] = g[b][a] = true;
  }
  vec o(n);
  rep(i, n) o[i] = i;
  ll res = 0;
  do{
    if(o[0]!=0) break;
    bool jud = true;
    for(int i = 0; i < n-1; i++){
      ll from = o[i];
      ll to = o[i+1];
      if(!g[from][to]) jud = false;
    }
    if(jud) res++;
  } while(next_permutation(o.begin(), o.end()));
  cout << res << endl;
}
```
### 解法
1から`N`までの順列全探索を用いて解いていく。必ず1からスタートするため先頭の要素が1でないときループを終了する。先頭の要素1の場合での順列の要素をすべて考え、条件が満たせるものをカウントしていく。
【セッションレポート】「SQL実行計画 – 主要RDBMS製品の比較(Oracle, MySQL, PostgreSQL)」に参加しました

# はじめに

本記事はDB Tech Showcase 2024 の1日目(7/11)において COSOL の渡部さんが講演された「SQL実行計画 – 主要RDBMS製品の比較(Oracle, MySQL, PostgreSQL)」のレポートです。

# 公式セッション紹介

> Oracle, MySQL, PostgreSQLを対象に、実行計画に関連することがらを比較することで、データベースに関する理解を深めることを狙ったセッションです。
セッション全体としてのストーリーは特になく、気になった点をピックアップしてお話しする形で進めます。
いずれかのRDBMS製品の実行計画についてある程度の知識があることを前提とします。上級者向けのセッションと位置づけ、懇切丁寧には説明しません。

# セッション資料

- [dbts2024発表資料 SQL実行計画 - 主要RDBMS製品の比較(Oracle, MySQL, PostgreSQL)](https://cosol.jp/download/)

# 概要／おすすめポイント

このセッションではSQLの実行計画に絞ってOracle Database, MySQL, PostgreSQLの比較を実施しています。データベースエンジンの比較では、構文やデータ型、関数などの比較はたまにありますが、SQLの実行計画自体の比較を見るのは初めてでしたので興味深かったです。
また、「見積時の実行計画」と「実行時の実行計画」の違いや 出力行数ではなく **アクセス行数** を確認しましょう、といったような実際に実行計画を確認するときに どっちだっけ？ と迷ってしまうような点にアプローチされているので、実行計画をあまり見ない方にもイメージしやすいと思います。

渡部さんがOracle DatabaseのSpecialistであり、Oracle Databaseエンジニアの観点から他のデータベースエンジンについて述べられています。私自身と同じ視点になるので、(私には)とても判りやすかったです。

# セッション内容の紹介

実行計画の説明から、それぞれのデータベースエンジンにおける実行計画の取得方法、見方について簡潔に説明されています。また、索引アクセスと結合アルゴリズムについても説明されているため、通常チューニングとしてはよくある「索引が利用されているか見てくれない？」とかには対応できるようになると思われます。

以下私が良いな、と思ったトピックについて記します。

- 実行計画＋統計の取得方法
    - 実行計画の予測と実測についての説明と、それぞれの取得方法、何に着目すべきかについて述べられていますので、最初によくある予測(estimated)だけ見てなかなか改善されないな、といったところで時間を使ってしまうようなことが避けられます
- 実行計画の読み方
    - (MySQLやPostgreSQLでは)マニュアルにもきちんと記載されていない実行計画のツリー構造の見方を、実際に検証結果を踏まえて説明されているため、実際に取得した実行計画を読むためのガイドにもなります
    - 統計の見方についても触れているため、実際の出力に対して怪しいところを見つけることができるようになります

もちろんそれぞれの中身について深く解説しているわけではないですが、実行計画自体は例え長い実行計画でも順番に見ていくことができますので、見方・順番についてさえ把握していれば、時間をかけて見ていくことである程度「この辺が問題なのでは？」というあたりをつけることはできると考えており、その目的は達成されているのでは、と考えてます。

# まとめ

内容については セッション資料 からダウンロードして頂ければと思いますが、統計などの考え方含めて一読しておくことで、自身で触ったことがないデータベースエンジンについても理解が深まると考えてます。

なお、「主要4種データベース製品（Oracle、MySQL、PostgreSQL、MS SQL Server）の相違点比較と 異種データベース製品活用における課題と解決」という資料も同じ場所からダウンロードできますので一緒に確認しておくとより理解が深まると思います。

#### おまけ（実行計画の見方簡易版）

業務系のシステム(OLTP系)で実行計画を見るとき、まずは以下に着目すると良いと考えてます。
1. FULL SCANがないか？(INDEXが利用されてほしい)
1. 1行取り出すのにINDEX RANGE SCANが利用されてないか？(UNIQUE SCANが利用されてほしい)

いずれも適切な索引が作成されているか？利用されているか？という観点になります。
そんな初歩は大丈夫でしょ、と思われる方もいらっしゃると思いますが意外と統計情報が適切なタイミングでとられてない、などでこのような状態になっていることがあります。基本の確認という事でまずはこの辺を確認すると良いと思ってます。

これは私自身のTIPSですので、ご参考まで。。

#### おまけ（システムリリース時の統計情報取得のタイミング）

性能テスト等を潜り抜け十分な性能を確保しているシステムでも、たまにリリース時に「性能が出ない！」というトラブルが発生することがあります。
大体、ゼロ件の状態で意図せず統計情報が取得されてしまった、というような状況で発生します。
特にリリース時において、ヒストリカルなデータはデータ量がある場合でも、トランザクショナルなデータ(例えば今日の取引データ)のようなものがゼロ件で始まる場合に、「リリースなので念のため全テーブル統計情報を取りましょう！」のようなことを実施してしまうと発生してしまう場合があります。
本質的にはどのテーブルがどのような状況か把握しておくことが大事で、それぞれのテーブルに対していつ統計情報を取るべきなのかを認識して計画しておくことで防ぐことができます。
また、リハーサルで本番と同じアクションをやって確認しておく、という事で流出を防ぐことができます。

こちらも私自身のTIPSですので、ご参考まで。。