OmniAICreator/Qiita-1.07M huggingface dataset:
Rails初心者の学習日記　 CRUDの基本

## はじめに
Railsの学習を始めたばかりの初心者です。私がRailsで学んだCRUD処理の基本について共有します。

## Railsとは
Rails（Ruby on Rails）は、Ruby言語をベースにしたWebアプリケーションフレームワークです。Railsの大きな特徴は、開発を迅速化し、簡素化するための多くの機能を備えている。

## CRUDとは
CRUDは「Create（作成）」「Read（読み取り）」「Update（更新）」「Delete（削除）」の頭文字を取ったもので、データベースの基本的な操作を指します。これらの操作は、Webアプリケーションにおいて非常に重要されるようです。

Create（作成）: 新しいデータをデータベースに追加します。
Read（読み取り）: データベースからデータを検索・取得します。
Update（更新）: データベース内の既存のデータを変更します。
Delete（削除）: データベースからデータを削除します。

## RailsでのCRUD処理
Railsでは、これらのCRUD操作を簡単に実装できる。ブログアプリケーションを例に説明します。

Create: 新しいログ記事を作成するためのフォームを用意し、createアクションを通じてデータベースに保存します。

Read: indexアクションを使って、すべてのブログ記事を表示し、showアクションで特定の記事を表示します。

Update: 記事を更新するためのフォームを用意し、updateアクションでデータベースの該当する記事を更新します。

Delete: 各記事に削除ボタンを設置し、destroyアクションで記事をデータベースから削除します。

## 学んだこと
RailsのCRUD処理の実装は、他のフレームワークや言語に比べて直感的で、短いコードで多くの機能を実現できることに驚きました。特に、rails generate scaffoldコマンドを使用すると、CRUDの基本的な構造を自動的に生成できるのは非常に便利だと感じました。

## まとめ
RailsでのCRUD処理は、データベース操作の基本であり、Webアプリケーション開発の核となる部分でこの学習過程を通じ、Railsの強力な機能と使いやすさを実感しました。引き続き、さらに深い知識を身につけていくことを楽しみです。
C/C++開発環境 : Visual Studio Code (Mac)

■ 前提

・Visual Studio Code、C/C++プラグインインストール済み。
・Xcodeインストール済み。(コンパイラを使用するのに必要。)
・コンパイラはClang(クラン)、デバッガはLLDBを使用する。

■ 手順
1. Cプログラムファイルを任意のフォルダに保存する。
2. VSCodeからCプログラムファイルを保存したフォルダを開く。
3. Cプログラムを開く。
4. 左端の「実行とデバッグ」アイコンをクリックし、「実行とデバッグ」ボタンをクリックする。
4. 構成の選択で「C/C++: clang++ アクティブファイルのビルドとデバッグ」を選択する。
⇒ この時点で、ビルド情報"tasks.json"が生成される。

5. 実行とデバッグで、「launch.json」ファイルを作成します。」をクリックする。
6. デバッガーの選択で、「C++ (GDB/LLDB)」を選択する。
7. 構成の追加ボタンをクリックし、「C/C++:(lldb)起動」を選択する。
8. 「"program": "プログラム名を入力してください (例:${workspaceFolder}/a.out)"」で任意のプログラム名を入力する。
⇒ ここをちゃんと入力しておかないと実行時に怒られる。

9. Cプログラムのタブをアクティブにして、実行とデバッグの緑矢印ボタンをクリックする。

⇒ デバッグコンソールに実行結果が出力される。
精度の高い計算

精度の高い小数点の計算プログラムを作りました

```Ruby
# 自分の得意な言語で
# Let's チャレンジ！！
input_line = gets
array1 = input_line.split(' ')
M = array1[0].to_f
p1 = array1[1].to_f
q1 = array1[2].to_f
ans1 = (M * p1 / 100).to_f
ans2 = (M - ans1).to_f
ans3 = (ans2 * q1 / 100).to_f
ans4 = (ans2 -ans3).to_f
puts ans4
```
SVNを捨ててGitを使う

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3427598/b1501277-a1fd-00c7-c8ce-a5b02193275a.png)

会社は7年間SVNを使用し、
社内コードリポジトリの安全性・セキュリティレベルを高めるとともに、近い将来急増する開発ニーズに応えるため、
コード リポジトリは、Subversion バージョン管理システムから Git に移動されました。
Gitは分散型バージョン管理システムであり、SVNよりも柔軟性とスピードに優れています。
特にブランチとマージの機能は非常に強力で、同時に複数の作業を行ったり、新機能の開発やバグ修正を行ったりすることが容易です。
また、履歴の管理やタグの付与、リバートなど、さまざまな便利な機能も備わっています。
Gitの学習にはさらに多くの魅力的な要素がありますので、これからも探求していくことを楽しみにしています。

以下は SVN と Git の基本的な違いに関する記事です。
- [GitとSVNはどう違う？](https://qiita.com/spm84/items/62f2e30cbd8c0ebf02a3)

開発中に変更履歴を保持しながらソースを svn から git に変換する方法。
- [Subversion(SVN) から Git への移行](https://qiita.com/spm84/items/a05d5a54b9510be90b65)
速報：自宅観測で録れた能登半島地震の波形

# はじめに

昨年末のアドベントカレンダーに寄稿した（大げさ）地震計をたまたま連続稼働している最中に能登半島地震が発生しました。

https://qiita.com/pirotan628/items/f0a4207e8b32295b82e4

前記事にあるように商用電源ではまだデータ品質に大きな問題がありますが、それでも確認できる振幅の地震動だったようです。

# 取得波形

![clipboard_240101_eq.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88076/b4c610db-2731-970a-bb78-ae5ea471e2fa.png)

気象庁発表の地震発生時刻から約1分後の波形とスペクトルです。P波の立ち上がりやS波の到達などは不明瞭です。後続の表面波については恐らく振幅の最大値を記録している時間帯ではないかと思います。また、表面波の終息がいつなのかも不明瞭です。

IRISの [Station Monitor](https://www.iris.edu/app/station_monitor/#Today/JP-JWT/map/) から高知の観測点で得られた波形と比較してみます。自宅観測点という性質上正確な位置は言えませんが、西日本同士での比較です。また、どちらも速度計です。

![スクリーンショット 2024-01-04 090118.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88076/9f4a3f81-879c-c42f-a4e4-a7836e7c7290.png)

波形の時間経過のパターンは概ね似ていると言えるでしょう。しかし、この波形だけではいつもの交通系ノイズと明確には区別できません。

# 交通系ノイズとの比較

![clipboard_240101_noise.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88076/01c3b1ed-2c3c-1034-0656-8d408b161960.png)

こちらが常時観測されている交通系ノイズの波形とスペクトルです。地震波形と異なるのは、10Hz以下の周期です。上の地震波形では10Hz以下のスペクトルが交通系ノイズに比べて大きく立ち上がって4Hz付近にピークが見られるのに対し、交通系ノイズでは15Hz付近のピークしか認められません。

使用しているセンサーが15Hz付近に固有周期があるため長周期は苦手だと思いますが、それでも10Hz以下の周波数が卓越していることから普段の地動ノイズとは明らかに異なることが分かります。

# おわりに

今回は地震の規模が大きく、発生時刻から波形を探すことができました。周波数特性からも明瞭な地震波形であることが分かりました。

バッテリーではノイズを抑えることができているので、商用電源を用いた連続観測でもP波の立ち上がりが見えるようにしたいところです。
C#とVB.NETでExcelのデータを検索する

## はじめに
Excelでデータを検索してハイライト表示することは、特定の条件に一致するセルや値を素早く特定し、目立たせるための便利な機能です。大規模なスプレッドシートを処理する際に特に役立ちます。手動での検索だけでなく、プログラミングを使用して特定のデータを検索してハイライト表示することも可能です。この記事では、C#およびVB.NETプログラムを使用してExcel内の指定されたデータを検索してハイライト表示する方法について紹介します。


## ツール
* Visual Studio 2022
* [Free Spire.XLS for .NET](https://www.e-iceblue.com/Introduce/free-xls-component.html)

このライブラリは、無料でExcelファイルを作成、編集、変換することができますが、ページ数の制限があります。または、有料版の製品の[無料トライアル](https://www.e-iceblue.com/TemLicense.html)を申し込むこともできます。

**有料版:**  [Spire.XLS for .NET](https://www.e-iceblue.com/Introduce/excel-for-net-introduce.html)

## インストール方法
1.[Free Spire.XLS for .NET](https://www.e-iceblue.com/Download/download-excel-for-net-free.html)をダウンロードします。
2.Visual Studioで新しいプロジェクトを作成します。
3.「Solution Explorer」>「References」を右クリックし、「Add Reference」>「Browse」を選択します。
4.BINフォルダ内のdllファイルを見つけて、「OK」をクリックします。

## 方法とコード
* **Workbook** クラスのインスタンスを作成します。
* **Workbook.LoadFromFile()** メソッドを使用して、Excel ファイルをロードします。
* **Workbook.Worksheets[sheetIndex]** プロパティを使って、指定したワークシートを取得します。
* **Worksheet.FindAllString(string stringValue, bool formula, bool formulaValue)** メソッドで、一致するテキストがあるセルをすべて検索しています。
* **CellRange.Style.Color** プロパティを使って、セルを強調する色を設定します。
* **Workbook.SaveToFile()** メソッドを使用して、結果ファイルを保存します。

**C#:**
```c#
using Spire.Xls;
using System.Drawing;

namespace FindHighlight
{
    class Program
    {
        static void Main(string[] args)
        {
            //Workbookクラスのインスタンスを作成する
            Workbook workbook = new Workbook();

            //Excelファイルをロードする
            workbook.LoadFromFile("Sample.xlsx");

            //最初のワークシートを取得する
            Worksheet sheet = workbook.Worksheets[0];

            //テキスト「500」を含むすべてのセルを検索する
            foreach (CellRange range in sheet.FindAllString("5000", true, true))
            {
                //セルを強調するための色を設定する
                range.Style.Color = Color.Yellow;
            }

            //結果ファイルを保存する
            workbook.SaveToFile("Result.xlsx", ExcelVersion.Version2016);
        }
    }
}
```
**VB.NET:** 
```vb
Imports Spire.Xls
Imports System.Drawing

Namespace FindHighlight
    Class Program
        Shared Sub Main(ByVal args() As String)
            'Workbookクラスのインスタンスを作成する
            Dim workbook As Workbook = New Workbook()

            'Excelファイルをロードする
            workbook.LoadFromFile("Sample.xlsx")

            '最初のワークシートを取得する
            Dim sheet As Worksheet = workbook.Worksheets(0)

            'テキスト「500」を含むすべてのセルを検索する
            Dim range As CellRange
            For Each range In sheet.FindAllString("5000", True, True)
                'セルを強調するための色を設定する
                range.Style.Color = Color.Yellow
            Next

            '結果ファイルを保存する
            workbook.SaveToFile("Result.xlsx", ExcelVersion.Version2016)
        End Sub
    End Class
End Namespace
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/26d00d57-a962-f40d-9fc9-9a863a11b727.png)
Spring Securityでログイン後のURLに付くcontinueクエリパラメータの正体

# 環境
- Spring Boot 3.2
- Spring Security 6.2

この記事の内容が該当するのは、Spring Security 5.8以降です。

# ある日気づいた
Spring Securityでログイン付きのWebアプリを作ってログインしたら、URLに`continue`というクエリパラメータが付いていました。

![スクリーンショット 2024-01-04 16.11.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/843d019f-26cc-5c26-b518-5bae20134cea.png)

こんなん付いてたっけ？と思ったので調べてみました。

# `RequestCache`とは
1. ログインが必要なURLにアクセス
1. 未ログインなのでログイン画面にリダイレクトされる
1. ログイン画面に正しいユーザー名・パスワードを入力
1. 認証完了後、1.でアクセスしたURLにリダイレクトされる

という流れは、認証付きのWebアプリでよくあります。Spring Securityではこれを実現するために、1.でのリクエスト情報（URLやクエリパラメータなど）を`RequestCache`という場所にキャッシュしています。`RequestCache`はインタフェースで、デフォルトの実装クラスは`HttpSessionRequestCache`です。名前の通り`HttpSession`にリクエスト情報をキャッシュします。

この`RequestCache`は`RequestCacheAwareFilter`で利用されます。Spring Security 5.7まででは、全リクエストでリクエスト保存＋取得処理を行っていたようです。

# Spring Security 5.8での改修
しかしこのリクエスト保存＋取得処理は、ログイン前にログイン必須なURLにアクセスしていた場合のみ必要なはずです。セッションがインメモリならばそんなに問題にはならないと思いますが、Spring Sessionなどを利用してセッションをRedisやRDBなどに保存していた場合は、リクエスト保存＋取得処理に（インメモリと比較すると）かなりの時間がかかります。

そこでSpring Security 5.8で、リクエストされたURLに`continue`クエリパラメータが含まれる場合のみキャッシュされたリクエストを取得するように改修されました。（キャッシュへのリクエスト保存は、相変わらず全リクエストで行われます）

Issue → https://github.com/spring-projects/spring-security/issues/11453

# `continue`はどこで付加されるか
ログイン成功後に呼ばれる`SavedRequestAwareAuthenticationSuccessHandler`が`DafaultSavedRequest#getRedirectUrl()`を呼ぶことで付加されます。

ソース → https://github.com/spring-projects/spring-security/blob/main/web/src/main/java/org/springframework/security/web/authentication/SavedRequestAwareAuthenticationSuccessHandler.java#L89

# 参考資料
- [Stack Overflow](https://stackoverflow.com/questions/75222930/spring-boot-3-0-2-adds-continue-query-parameter-to-request-url-after-login)
- [Spring Security Reference](https://docs.spring.io/spring-security/reference/6.1/migration/servlet/session-management.html#requestcache-query-optimization)
- [HttpSessionRequestCacheのソースコード](https://github.com/spring-projects/spring-security/blob/main/web/src/main/java/org/springframework/security/web/savedrequest/HttpSessionRequestCache.java)
抽選ツール③

***抽選結果***をエクセルに書き出し、自動でエクセルを開くように、**抽選ツール**を改良しました。

```python3
####################################################
###   お題抽選ツール
####################################################

#ランダムモジュールを呼び出す
import random
import openpyxl
import subprocess

#配列を定義する
array1 = []
array2 = []
#人数変数
N = 0
#エクセルファイルのファイル名変数
out_file = "prezen1.xlsx"
wb = openpyxl.load_workbook(out_file)
#書き込むワークシートを定義する
ws = wb['select']
#行数の定義
start_row = 3


#正の整数が入力されるまで繰り返す
while True:
  try:
    N = int(input("登録人数を指定してください\n"))
    if N <= 0:
      raise ValueError("error!")
    else:
      break
  except ValueError as e:
    print("文字列、小数、負の整数、0を入力しないでください")
    print("正の整数を入力してください")

#配列に名前を登録する
for i in range(0,N):
  name = input("名前を入力してください\n")
  array1.append(name)

#配列にお題を登録する
for j in range(0,N):
  title = input("プレゼンのお題を入力してください\n")
  array2.append(title)

#配列の要素をランダムに並べる
random_array1 = random.sample(list(set(array1)),N)
random_array2 = random.sample(list(set(array2)),N)

#ランダムに並べた名前を1行ずつエクセルファイルに出力する。
for k in range(0,N,1):
  man1 = random_array1[k]
  title1 = random_array2[k]
  try:
    with open(out_file,mode='a') as f:
      #エクセルファイルに追記モードで書き込む
      ws.cell(row=start_row,column=2).value = man1
      ws.cell(row=start_row,column=3).value = title1
      start_row += 1
  except:
    print("エクセルファイルが開いたままです。閉じてください")
    exit()
#エクセルファイルを保存する
wb.save(out_file)
#エクセルファイルを開く
subprocess.Popen(['start',r'prezen1.xlsx'],shell=True)
```
今日のあなたはナニモン？ -Digimon API-

## はじめに
新年の書き初めにしようと考えていた個人開発で、とにかく速く作ることを意識しました。
制作日数は1日で、[DAPI: Digimon API](https://digimon-api.com/)を使った、毎朝の占い番組・アプリ？のような用途を想定しています。<font color="lightgray">……クソアプリと言わないで</font>

## 作ったもの

![digiView-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368730/8149fca8-8b24-1b38-6913-5222f0f65a8a.gif)

見ていただいた通りなのですが『あなたがナニモンかチェック』ボタンを押下すると適当なデジモンが表示されます。
当初は**占いというテーマ**を意識していたので一日一回しかデジモンを表示できないようにしようかと思ったのですが、その日がスカモンだったり、ヌメモンだったりした人の気持ちを考えて何度もチェックできるようにしました。
<font color="lightgray">スカモンやヌメモンが好きな方がいらしたら申し訳ございません</font>

こだわったことと言えば制作スピードくらいなのですが、他のこだわりもいくつか挙げていきたいと思います。

## ここら辺にこだわった
- デジモンのランダム表示
これは**占いというテーマ**から外せない必要要件でした。[DAPI: Digimon API](https://digimon-api.com/)にはデジモンデータの総数を取得できるところが用意されていたので、それを用いてランダム表示する仕組みにしました。

```typescript
:
const randNum: number = Math.floor(Math.random() * data.pageable.totalElements); // 総数をベースにランダム数値を生成
setRandNum((_prevRandNum) => randNum); // ランダム数値をState管理
const singleDigimonData: Response = await fetch(`https://digi-api.com/api/v1/digimon/${randNum}`); // ランダム数値をエンドポイントに指定
:
```
先ほども触れましたが一日一度ではなく、何度でもその日の自分が『ナニモン』かチェックできます。

![digiView-3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368730/d857752b-230f-eb1e-987f-73b3bb8addb4.gif)

- 将来性（進化後）と経歴（進化前）の表示
APIを見てみると、当該デジモンの進化後・進化前のデータも取得できることが分かったので、これも何かに使えないかと考えて追加したのが当機能です。

![スクリーンショット 2024-01-04 151427.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368730/c6c9753a-86bd-1ee0-cbaf-df44eb3979d2.png)

「たとえ今日がヌメモンでも、**メタルグレイモンになれる可能性がある**んだ」って考えると毎朝晴れやかな気持ちで一日を始められそうですよね？
まぁご覧の通り、スカモンルートもあるのですが……。

![スクリーンショット 2024-01-04 151941.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368730/e3987dd3-5cdb-86ef-81ba-0fd6e23adb8f.png)

一方で、自身の振り返りもできるように今までのキャリア（進化前）も確認できるようにしてあります。
「あの頃この程度だった自分も今ではここまでできるって成長したなぁ～」と自分をたまには褒めてあげてください。
他人と自分を比べるのではなく、昨日までの自分と比べて日々精進に努めたいものです。

![スクリーンショット 2024-01-04 151722.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368730/78c3f626-c342-70d2-59c4-0e4dc66f225d.png)

ちなみに、進化後または進化前のデータがないデジモンの場合は**将来性無しや経歴不明**となります。

![スクリーンショット 2024-01-04 152539.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368730/81dfcc03-2046-1aec-7b1f-258b9ccd1cc4.png)

いわゆるカンスト？状態になっても**将来性なし**になります。
そのような方々は、ここまで究められて素晴らしいという他ないですが驕り高ぶることなく謙虚と思いやりを忘れないようにしていただきたいものです。「その界隈では有名だがその界隈が狭すぎて世間には通じない」という心構えを持っていたいですね。

- なりたいデジモンになれる
**「どうしてもオメガモン（omgemon）になりたい！」**
**「今日は大事な商談がある日だからウォーグレイモン(war greymon)の気分だ！」** 
**「デュークモン（dukemon）みたいに気品をまといたい」** 
というニッチな方々のニーズにお答えすべくフォームを用意しました。

![digiView-2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368730/c229e47c-3288-d8ae-a669-c3550d404719.gif)

しかし、デジモン名は**英語名**で入力していただく必要があります。かたじけなし。

## さいごに
ここまで読んでいただき、ありがとうございました。
GitHubを貼っておきますので気になった方は自由にご利用ください。

https://github.com/Benjuwan/digiView

## 参照情報
https://digimon-api.com/
systemdからシェルスクリプトを起動するとif文の正規表現が使えない？

# はじめに
タイトル通りです。これで1時間くらいハマりました。
原因が全く分からずムカついたのでメモ。

# 結論
- Shebangが無かった
    - `#!/bin/bash`を指定する事
- systemdはシェルスクリプトの駆動にbashを使用していない
- 正規表現を使ったif文はshからは使えない

# いきさつ
実行環境はRaspbian/Ubuntu 22です。他のディストリビューションだとどうなるかは知りません。

こんな現象が起きました。
- シェルスクリプト単体はbashから動く
- シェルスクリプトをsystemdから起動すると動かない

ループの中でif文に正規表現を使うだけのテストコードです。
終了するとサービスにならないので無限ループとしています。
``` shell:test.sh
test=kusounkokuso
while :; do
        if [[ ${test} == *unko* ]]; then
                echo "oh yes"
        fi
        sleep 3600
done
```

シェルの出力はこう。予想通りの動作です。
``` bash
$ ./test.sh
oh yes
```

サービスとして登録した場合の`systemctl status`の出力はこう。
``` bash
× test.service - kuso
     Loaded: loaded (/etc/systemd/system/test.service; disabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Mon 200000024-01-01 00:00:00 JST; 10s ago
    Process: 99999 ExecStart=/usr/bin/test.sh (code=exited, status=203/EXEC)
   Main PID: 99999 (code=exited, status=203/EXEC)
        CPU: 2ms

 1月 01 00:00:00 shit systemd[1]: test.service: Scheduled restart job, restart counter is at 32.
 1月 01 00:00:00 shit systemd[1]: Stopped kuso.
 1月 01 00:00:00 shit systemd[1]: test.service: Start request repeated too quickly.
 1月 01 00:00:00 shit systemd[1]: test.service: Failed with result 'exit-code'.
 1月 01 00:00:00 shit systemd[1]: Failed to start kuso.
```

明らかにsystemdが原因ですがエラーメッセージの内容が無いので原因が良く分りません。

# どうする
Shebangからbashを指定しました。
``` diff_shell:test.sh
+ #!/bin/bash
test=kusounkokuso
while :; do
        if [[ ${test} == *unko* ]]; then
                echo "oh yes"
        fi
        sleep 3600
done
```

`systemctl status`の出力も正常です。プロセスツリーにbashがいる事に注目してください。
``` bash
● test.service - kuso
     Loaded: loaded (/etc/systemd/system/test.service; disabled; vendor preset: enabled)
     Active: active (running) since Mon 300000024-01-01 00:00:00 JST; 3s ago
   Main PID: 99999 (test.sh)
      Tasks: 2 (limit: 9239)
     Memory: 528.0K
        CPU: 4ms
     CGroup: /system.slice/test.service
             ├─99999 /bin/bash /usr/bin/test.sh
             └─999999 sleep 3600

 1月 01 00:00:00 shit systemd[1]: Started kuso.
 1月 01 00:00:00 shit test.sh[99999]: oh yes
```

修正後のシェルスクリプトをbashではなくshに突っ込みました。Shebangは無視されるようです。
``` bash
$ sh ./test.sh
/usr/bin/test.sh: 3: [[: not found
```

# おわりに
くだらねえーーーーーーー
Gitの基本

## 概要
社内でGitについての勉強会がありましたので、その時学習した内容と自分で調査した内容を纏めて、アウトプットしてみました。
記事としては、Gitの基礎的な内容となっています。

## Gitとは？
ソースコードや変更履歴を管理するために使用される、代表的な分散型バージョン管理システムです。
Gitによってファイルのバージョンを管理することができるため、他の作業者にソースコードを上書きされても、簡単に元の状態に戻すことができます。
## Gitを使用するメリット
- 古いバージョンから新しいバージョンのファイルまで管理することができる
- 簡単に古いバージョンに戻すことができる
- チームでファイルや変更履歴をスムーズに共有することができる
## Gitインストール方法
### Linux
バイナリのインストーラを使用し、Linux上にGitと主な関連ツールをインストールする場合、大抵はディストリビューションに付属する基本的なパッケージ・マネジメント・ツールを使用。
`sudo yum install git-all`

UbuntuのようなDebianベースのディストリビューションを使用している場合、apt-getでインストールする。
`sudo apt-get install git-all`

### Mac
GitのWebサイトからインストーラをダウンロードします。

https://git-scm.com/download/mac

上記の手順の代替として、Homebrewを使用してGitをインストールする方法もあります。
以下のサイトを参考にして下さい。

https://kinsta.com/jp/knowledgebase/install-git/#mac-3

### Windows
macと同様にGitのWebサイトからインストーラをダウンロードします。

https://git-scm.com/download/win

## Configuring git
Gitの設定（ユーザ名やメールアドレス等）を`git config`で確認・変更します。

Gitの設定ファイルは３種類あります。
| 種類 | 対象範囲 | 場所 |
|:-:|:-:|:-:|
| system  | システム全体（全ユーザの全リポジトリ）  | /etc/gitconfig  |
| global  | 該当ユーザの全リポジトリ  | ~/.gitconfig  |
| local  | 該当リポジトリ  | repository/.git/config  |

system、global、localの順番で読み込まれます。

```linux:bash
$ git config --global user.name "ユーザ名"
$ git config --global user.email "メールアドレス"

$ gti config -l
##有効になっている設定項目と設定値が全て表示される。
```

`git config -e`で設定ファイルをエディタで直接編集することもできます。
## Git Clone
指定したリポジトリをカレントディレクトリ（ローカル環境）に複製することができます。
```linux:bash
$ git clone リポジトリパス
```
### オプション
| オプション | 説明 |
|:-:|:-:|
| --branch(-b)  | クローンしたいブランチを指定  |
| --quiet(-q)  | クローン時のメッセージを非表示  |
| --origin(-o)  | originに別名をつける  |
| --depth  | 指定数のコミットのみを取得  |
| --no-checkout  | チェックアウトを行わない  |
## Git Branch
Gitに新しいブランチを作成します。
```linux:bash
#新規ブランチの作成とブランチの切り替え
$ git checkout -b ブランチ名

#ブランチの削除
$ git branch -d ブランチ名

#利用できるブランチと現在のブランチの確認
$ git branch
```
## add関連
変更したファイルをステージングエリアにステージ（add）する。
```linux:bash
#すべての変更したファイル
$ git add .

#ファイル単位でadd
$ git add ファイル名

#ディレクトリ単位でadd
$ git add ディレクトリ名
```
ステージングエリアにaddした変更点をアンステージします。
```linux:bash
#すべてのステージをキャンセルする
$ git restore --staged .

#ファイル単位でキャンセルする
$ git restore --staged ファイル名

#ディレクトリ単位でキャンセルする
$ git restore --staged ディレクトリ名
```
## commit関連
ステージした変更点をFeatureブランチにコミットします。
```linux:bash
git commit -m "コミットメッセージ"
git push origin ブランチ名
```
直前のコミットを取り消します。
```linux:bash
#コミットした内容をステージングエリアに戻す
$ git reset --soft commit-hash

#すべて無かったことにする（コミット前の状態に戻す）
$ git reset --hard commit-hash
```
## Rebase/Merge関連
### リベース
リベースには、「指定したコミットをブランチに変えて作り直したり、一つにまとめたりして、ログをきれいにするコマンド」です。
rebaseは２種類の使い方が存在します。
- 別々のブランチで伸ばした開発コミットを繋げ直す。
- 複数のコミットを1コミットにまとめる。

```linux:bash
#別々のブランチで伸ばした開発コミットを繋げ直す。
$ git rebase 繋ぐ元にするブランチ名

#複数コミットを１コミットにまとめる
$ git rebase -i ひとまとまりにする地点の一つ前のコミットID
```
### マージ
他のブランチの更新を取り込む処理です。
```linux:bash
$ git merge　取り込みたいブランチ 
```
## 参考文献
* https://mteam.jp/column/00029/
* https://note.nkmk.me/git-config-setting/
* https://tech-blog.rakus.co.jp/entry/20220624/git
* https://www.atlassian.com/ja/git/tutorials/using-branches/git-checkout
* https://www.sejuku.net/blog/71919
* https://www.sejuku.net/blog/71003
Linuxでの調査時に高頻度で使用してきたコマンドまとめ

## この記事について
この記事は、Linux上でコマンドをそこそこ実行してきた私が**独断と偏見**でよく使う5大コマンドをまとめたものです。
痒い所に手が届くような内容になることを願って記します…。

## コマンドたち
### ①netstat -anp | grep "Listen "
:::note warn 
**netstat**コマンドは、使用しているディストリビューションによっては**ss**コマンドに置き換わっている可能性があります。
:::
#### 実現できること
LISTENしているポートを確認できます。
アプリケーションやミドルウェアに接続できない場合のトラブルシュートに使用できます。

#### 使用方法
ポートの状況を調べたいサーバ上でコマンドを打つだけです。
`127.0.0.53:53`や`:::80`の箇所：　LISTENしているIPアドレスとポート
`0.0.0.0:*`や`:::*`の箇所：　　　 接続する側のIPアドレスとポート

このような状況ではSSL設定したはずなのに、`443`ポートが開いていないぞというような形で調査ができます。
```
$ netstat -anp | grep "LISTEN "
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -
tcp6       0      0 :::80                   :::*                    LISTEN      -
```
<br>

### ②lsof -i:<ポート番号>
#### 実現できること
ポートが何によって開放されているかを確認できます。

#### 使用方法
コマンドの`<ポート番号>`の箇所を調べたいポート番号に置き換えてコマンドを打ちます。
COMMANDの箇所が`apache2`になっているので、`80`番ポートを開放しているのは`apache2`であると分かります。

```
$ sudo lsof -i:80
COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
apache2  374     root    4u  IPv6  27362      0t0  TCP *:http (LISTEN)
apache2 1011 www-data    4u  IPv6  27362      0t0  TCP *:http (LISTEN)
apache2 1012 www-data    4u  IPv6  27362      0t0  TCP *:http (LISTEN)
```
<br>

### ③grep -lR "<検索文字列>" <ディレクトリ名>
#### 実現できること
指定したディレクトリ配下の検索文字列を含むファイルを一覧取得できます。
~~エディタでやれは禁止。~~

#### 使用方法
コマンドの`<検索文字列>`を検索したい文字列に置き換え、`<ディレクトリ名>`を配下を検索したいディレクトリ名に置き換えてコマンドを打ちます。
特定の変数が使用されているファイルの一覧を抜き出す際などに利用できます。

```
# ディレクトリ/ファイル構成
$ tree
.
├── test1
└── test_dir
    ├── test2
    └── test_dir2
        └── test3


$ cat test1
aaa

$ cat test_dir/test2
bbb

$ cat test_dir/test_dir2/test3
aaabbb
```

```
$ grep -lR "aaa" ./
./test1
./test_dir/test_dir2/test3
```

<br>

### ④Ctrl + R
#### 実現できること
コマンドの履歴を検索できます。
あのめっちゃ長いコマンドもう一回打ちたい…を実現できます。

#### 使用方法
Ctrl + Rを押すことで検索画面に切り替わります。
その後、検索文字列を打つことで検索文字列を含むコマンドの中で最後に打ったコマンドを呼び出せます。

ここでは、`111`を検索文字列として、`echo 111`が履歴から検索されています。
この状態から、`Enter`で実行、`Tab`でコマンドの表示、`Ctrl + R`でさらに古いコマンドの検索ができます。
```
# 111で検索した状態
(reverse-i-search)`111': echo 111

# Enter押下時(コマンドが実行される)
$ echo 111
111

# Tab押下時(コマンドは実行されていない状態)
$ echo 111

# さらにCtrl + Rを押下時(さらに古いコマンドの検索)
(reverse-i-search)`111': echo 111222
```

<br>

### ⑤for
#### 実現できること
繰り返す処理を行うことができます。
一定の間隔でコマンドを打ったり、複数のサーバにコマンドをばらまいたりできます。
調査したいサーバをローラーで調査する際などに使用していました。

#### 使用方法
以下の構文で繰り返し処理が実行できます。
```
for <実際の処理に使用する変数> in <変数に格納するもののリスト>; do <コマンド>; done
```

使用する際のイメージはこんな形です。
`echo`の部分を`ssh`に変えることにより、サーバへのローラー処理などが可能になります。
```
$ _hosts="test1 test2 test3"
$ for host in $_hosts; do echo "====$host===="; echo "hello $host"; done
====test1====
hello test1
====test2====
hello test2
====test3====
hello test3
```

## あとがき
コマンドを直接打つ機会も減っていると思いますが、なにかの助けになれば幸いです。
こんなのも便利だよがあれば、是非教えてください！
Docker で MariaDB を 利用する

# はじめに
Docker(compose) での MariaDB 利用方法です。
普段は、PostgreSQLを使うことが大半ではありますが、触ってみました＆書き残しメモです。

# 確認環境
- WSL2(Ubuntu22.04.3 LTS)
- Docker (24.0.6)
- Docker Compose (2.4.1)
- MariaDB (10.11.6-jammy)

# フォルダ構成

```
[projectfolder]
 ├─ compose.yml
 ├─ Dockerfile
 ├─ conf.d
 │    └─ my.cnf
 └─ initsql
    └─ 10_sample1.sql
```

# コード
```yml:compose.yml
services:
  db:
    build:
      context: .
    ports:
      # ポート設定
      - '3306:3306'
    environment:
      # デフォルトのDB
      MARIADB_DATABASE: defaultdb
      # デフォルトの一般ユーザー
      MARIADB_USER: dbuser
      # デフォルトの一般ユーザーのパスワード
      MARIADB_PASSWORD: dbpass
      # 管理者(ユーザー名はroot)のパスワード
      MARIADB_ROOT_PASSWORD: rootpass
      # タイムゾーン
      TZ: Asia/Tokyo
    volumes:
      # 初回実行するSQL(フォルダごと)
      - ./initsql:/docker-entrypoint-initdb.d
      # 設定ファイル
      - ./conf.d:/etc/mysql/conf.d
      # DBの永続化
      - db-volume:/var/lib/mysql

# ボリューム設定（永続化のため）
volumes:
  db-volume:
    name: mariadb-data
    driver: local
```

```Dockerfile:Dockerfile
# mariadb(投稿時のLTSバージョン)
FROM mariadb:10.11.6-jammy

# ユーザー切り替え
USER mysql
```

```conf:conf.d/my.cnf
# mysqlサーバーの設定
[mysqld] 
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

# クライアントツールの設定
[client] 
default-character-set=utf8mb4
```


```sql:10_sample1.sql
-- 事前に実行したSQLをファイル化しておく

-- サンプルのテーブル作成
create table sample1(
    id int auto_increment,
    col1 text,
    col2 text,
    primary key (id)
);

-- サンプルのテーブルにデータを登録
insert into
    sample1(col1, col2)
values
('aaa', '1111'),
('bbb', '2222');
```

# 実行方法
以下のシェルを実行します
```shell:shell実行
# プロジェクトフォルダに移動
cd [projectfolder]
# 設定ファイルのパーミッションを変更
sudo chmod 655 conf.d/my.cnf
# コンテナ立ち上げ
docker compose up -d
```


# 余談
1. WSLの場合
    WSLの場合、`/mnt/...` 以下に設定すると、パーミッションが変更できませんので、Windows管理の保存領域以外のパスを利用しないといけません。
    ※起動はされますが、下記のようにDockerのログに `my.cnf` が読み込めない旨のWarningが表示されます
    
    ```
    mariadb-db-1  | Warning: World-writable config file '/etc/mysql/conf.d/my.cnf' is ignored
    ```
    
    また、デフォルトユーザーで構築したい場合には、Dockerfileに
    ```Dockerfile
    RUN groupmod -g 1000 mysql
    RUN usermod -u 1000 mysql
    ```
    を入れてGID,UIDを1000にしても良いかも
　
1. 文字コード設定が反映されているかの確認
    以下のSQLを実行すると、文字コード系の設定が表示されます
    ```SQL:SQL実行
    show variables like "collation_server%";
    +------------------+--------------------+
    | Variable_name    | Value              |
    +------------------+--------------------+
    | collation_server | utf8mb4_unicode_ci |
    +------------------+--------------------+
    ```
    ※失敗時は utf8mb4_general_ci となる

# 最後に
`docker compose up -d` で実行すると、設定ファイルが読み込めていないことに気づけませんでした。まずは、 `-d` のオプションなし(ログ表示)でやってみることも大事ですね…
2024年1月 AIOps 定点観測

# 概要
AIOps の動向や学習のため、Google で AIOps を検索した結果を記録している記事です。

# 2024年1月4日の検索結果 (リスティング広告)

![20240104_AIOps_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345504/e2faad00-75b8-4842-5494-dbb3c8663f98.png)

* Dynatrace
* Splunk
* ServiceNow
* PureStorage

Dynatrace がトップで Splunk と ServiceNow が続いています。

先月の結果はこちら --> [2023年12月 AIOps 定点観測](https://qiita.com/mkodera/items/f8deb80e16ce805bb506)

# 2024年1月4日の検索結果 (広告以外)

![20240104_AIOps_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345504/2874926f-0175-32be-497e-d87c4c3d95fe.png)

* HPE
* Splunk
* 日立製作所
* IBM
* ビジネス+IT

HPE がトップで Splunk と日立製作所が続いています。ビジネス+IT の記事が5番目に表示されました。

先月の結果はこちら --> [2023年12月 AIOps 定点観測](https://qiita.com/mkodera/items/f8deb80e16ce805bb506)
リソース ・Elementのまとめ

[Flowに関するまとめページに戻る](https://qiita.com/Keiji_otsubo/items/55ebc9c634a3216f3990)

------------

+ [レコード トリガー フロー: 保存前と保存後](https://qiita.com/Keiji_otsubo/items/8884a9278767f57ebeab)
+ [衝撃だ、Map変数が使えない。](https://ideas.salesforce.com/s/idea/a0B8W00000GdfJnUAJ/provide-the-ability-to-use-maps-in-flows)
+ [フローでMap変数を使う](https://qiita.com/Keiji_otsubo/items/8d08debd4ea7d753423c)

# リソース : [リソース](https://help.salesforce.com/s/articleView?id=sf.flow_ref_resources.htm&type=5)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9ac4e0b8-a5ba-f2d7-cd10-6d0f37417169.png)

+ [フロー変数に関する考慮事項](https://help.salesforce.com/s/articleView?id=sf.flow_considerations_feature_variable.htm&type=5)
+ [Flow Resource: Stage](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007T57MU)
+ [フローのリソース: $Flow グローバル変数](https://help.salesforce.com/s/articleView?id=sf.flow_ref_resources_system_variables.htm&type=5)

# Element : [フロー要素](https://help.salesforce.com/s/articleView?id=sf.flow_ref_elements.htm&type=5)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/5601f5ee-74c5-1566-409d-cfbd9bdb9fcf.png)
GitHub の Jupyter Notebook を Google Colab で実行する方法

# 要約
Github　の URL(例: https://github.com/yoshidashingo/langchain-book/blob/main/chapter4/notebook.ipynb) をコピーして、「ファイル」→「ノートブックを開く」→「GitHub」。

# 質問と回答
:::note warn
https://github.com/yoshidashingo/langchain-book/blob/main/chapter4/notebook.ipynb のようなファイルを Google Colab 上で実行する方法を教えてください。
:::

:::note info
GitHubにあるJupyter Notebookファイル（.ipynb）をGoogle Colabで実行する方法は以下の手順で行います：

1. **GitHubのJupyter NotebookファイルのURLをコピーする**:
   - まず、実行したいGitHubのJupyter Notebookファイルのページにアクセスしてください。
   - そのページのURLをコピーします。

2. **Google Colabを開く**:
   - お使いのブラウザで[Google Colab](https://colab.research.google.com/)にアクセスしてください。

3. **ファイルを開く**:
   - Google Colabの画面で「ファイル」メニューを開き、「ノートブックを開く」を選択します。
   - 開いたウィンドウの上部にある「GitHub」タブをクリックします。

4. **URLを貼り付けてノートブックを開く**:
   - 「GitHub」タブにある検索バーに、先ほどコピーしたGitHubのJupyter NotebookのURLを貼り付けます。
   - 検索結果に表示されたノートブックをクリックして開きます。

5. **ノートブックを実行する**:
   - Google Colabでノートブックが開かれたら、各セルを実行していきます。セルを実行するには、セルを選択して「Shift」+「Enter」を押すか、セルの左側にある再生ボタンをクリックします。

6. **必要に応じてランタイムを変更する**:
   - 特定のライブラリやリソースを使用する場合は、ランタイムのタイプを変更する必要があるかもしれません。これを行うには、「ランタイム」メニューから「ランタイムのタイプを変更」を選択し、必要な設定を行います。

これらの手順を実行することで、GitHubにあるJupyter NotebookファイルをGoogle Colab上で開き、実行することができます。
:::
コードの可読性・保守性気にしてる？

# 「初めに」よりさらに初めに
株式会社アイスタンダードの高野です。
この記事は元々社内の主に新人用に作成していましたが、
あまり社内で連携されることがなくて寂しかったのでqiitaにも投稿することにしました。
記事内に問題がある場合はコメントをくださると嬉しいです。

# 初めに
コードを書く時に必要な事はた〜くさんありますが、今回可読性と保守性について記事を書くのは以下の理由のメリットがあると考えたからです。

1. 長期的にプロジェクト全体に貢献することができる
2. 可読性と保守性が高いコードが書けると気持ちよくなれる
3. 過去の自分を怨まなくて済む

# 本編
まず定義とメリットについて確認します。

## 可読性とは？
https://www.itnavi.jp/words/%E5%8F%AF%E8%AA%AD%E6%80%A7

> 特に作成したプログラマー以外の者がソースコードを見た時にそのプログラミングの目的や作成したプログラマーの意図を容易に読み取れるかどうかのこと。

## 可読性のメリット
https://www.capa.co.jp/archives/7383

> - 機能の拡張や修正が容易になる
> - 開発時間の短縮に繋がる

以上が可読性の定義です。

`特に作成したプログラマ以外の者`とありますが、`未来の自分`も加えておいてください。3ヶ月たったら大体の記憶は消えるので他人と同じようなものです。

極端な例ですが、
```
int a = 26;
```
まずパッと見で「26ってなんの数字やねん、変数名aって舐めすぎやろ」って思ったんじゃ無いでしょうか。

それは26からもaからも意味が読み取れないからでしょう。

こういうコードは読解する際に、
- 意味を汲み取るために本筋の読解とは別の読解を始めないといけない
- 無駄な思考が脳の容量を食うから疲れる
- つっこんでしまう

など、とにかく時間を食ってしまい修正に無駄なコストを掛けてしまいます。

修正するとすればこうでしょうか。
```
// アルファベットの総数
const int alphabetCount = 26;
```
こうすると分かりやすいですね。見ただけで意味が分かる。こんな感じのことを可読性っていいます。

コメントはあると親切でいいですが、無理に変な事を書いて読む人を困惑させないように気をつけましょう。

特に簡単な可読性を上げるためのテクニックを伝授？陳列？します。ちょっとでも覚えておくと便利だと思います。

- 名前と中身にズレがないように
getXXXなのに中で更新とかしたらわかんないよ
```
int getName() {
    // getNameなのに関数内でユーザーのアップデートを行っている
    updateUser();
    return "太郎";
}
```
変数名を変えるか、```updateUser()```を呼び出し元で呼ぶようにするようにしよう！！

- ネストの頭にreturnつけると分かりやすいよ

そこで終わるってすぐわかるから飛ばせるんよ
処理が長すぎるときに使えると思う
```
if(!isPen){
    return ressult;
}else{        
    if(!isPineapple){
        return ressult;
    }else{    
        if(!isApple){
            return ressult;
        }else{
            ~~ 処理 ~~
        }
    }else{
        ~~ 処理 ~~
    }
}else{
    ~~ 処理 ~~
}
```

- 計算結果はreturnできる
```
const int alphabetCount = 26;

// return trueになる
return (alphabetCount == 26)
```
コードがすっきりするね

- 型をしっかり指定する（言語によってはいらない）
型最高！！！~~型ない言語は使うな！！！（過激派）~~

## 保守性とは？
https://e-words.jp/w/%E4%BF%9D%E5%AE%88%E6%80%A7.html

> - 誤りや不具合の発見・修正のしやすさ
> - 事前に予定されていなかった仕様変更や機能追加などの行いやすさ
> - ソースコードの読みやすさ（可読性）

## 保守性のメリット
保守性とは?の3点そのまま

https://small-livehack.com/goodcode/

大体可読性高かったら保守性も高くなるから特筆して書くことなかったわ！

なのでコードに直接関係ないとこでいうとアーキテクチャやドキュメントとかあると思うけど、内容が被りそうやからここでおしまい！

※ちなみに基本情報や応用情報を勉強している時に出てくるCIAとは似ているだけで関係ない。
フローの変更点



+ [フローのUpdate Triggering Record　アクションは無くなった？](https://qiita.com/Keiji_otsubo/items/99e10e3a10522b177a20)

# フローのボタンの表示の仕方が変わった？ 202310 Winter24

Done button will be visible in Free-from mode not in auto layout please switch the flow in Free-from.

完了ボタンは、自動レイアウトではなくフリーフロム モードで表示されます。フローをフリーフロムに切り替えてください。

+ [フローの設定が変わった？](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007VfyW4)

https://trailhead.salesforce.com/content/learn/modules/flow-troubleshooting/fix-issues-caused-by-a-null-value-in-a-flow?trailmix_creator_id=jcespedes88&trailmix_slug=week-13-alx-salesforce-administrator-programme

トレイルヘッドの例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a09b80dd-21ae-2a9d-0052-525a16da5456.png)

今の表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/02264880-e31e-5d9f-ad8a-8a48a586da3a.png)

:::note
The functionality seems to be the same as below.

Recipient Address List: This is a comma-delimited list of the recipients' email addresses.
https://salesforcetime.com/2023/06/04/different-ways-of-sending-emails-from-flow/
:::

+ [API バージョン 54.0 でのフローおよびプロセス実行時の改善](https://qiita.com/Keiji_otsubo/items/b81da734159c64d33192)
+ [Winter '23 の 10 個の新しい Salesforce フロー機能](https://qiita.com/Keiji_otsubo/items/bc4dd2febc09db476c6f)
+ [Spring’22でリリースされたレコードトリガフローの新機能などなど](https://www.n-sysdes.co.jp/blog/27243/)
Power BIとは

# Microsoft Power BIとは
ソフトウェア ツール、アプリ、コネクタの包括的なセットで、データを対話型の分析情報に変換します。 さまざまなデータ ソースに適応し、組織の複雑さに合わせて仕立て上げることができます。

# Power BI のコア コンポーネントと構成要素
Power BI Desktop: データセットと視覚化で構成されるレポートを作成します。
Power BI サービス: 発行されたレポートからダッシュボードを作成し、アプリでコンテンツを配布します。
Power BI Mobile: モバイル向けに設計された Power BI サービスコンテンツに外出先でアクセスします。

#Power BI サービスとデスクトップの違い
Power BI Desktop と Power BI サービスを比較する
https://learn.microsoft.com/ja-jp/power-bi/fundamentals/service-service-vs-desktop

以下の図の一部のタスクは Power BI Desktop でも Power BI サービスでも実行できます。 ベン図の外側の 2 つの領域は、Desktop アプリケーションまたは Power BI サービスに固有の機能を示しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555220/9d28bd42-b049-9feb-250c-ba505d2b39d9.png)

#Power BI と Tableau の違い

https://frogwell.co.jp/blogs/powerbi-tableau/
https://www.kuix.co.jp/da-sys/?p=162
SpringBootで作ったRestAPIをDockerで動かす

## SpringBootで作ったRestAPIをDockerで動かす

### 環境情報

- windows10 Enterprise
- Docker Desktop 4.25.2

### 流れ

※[SpringBootでHelloWorld表示](https://qiita.com/tg0aeh/items/f383fedfe13160988847)を行ってる前提

1. Docker インストール
1. Dockerfile 記述
1. Maven でビルド
1. Docker イメージ作成
1. Docker 実行
1. Hello World 表示

### 手順

[公式の手順](https://spring.pleiades.io/guides/topicals/spring-boot-docker/)を参考に作成

1. Docker インストール  
   以下のリンクを参考  
   [Windows に Docker Desktop をインストール](https://docs.docker.jp/docker-for-windows/install.html)
1. Dockerfile 記述  
   SpringBoot のプロジェクト内に Dockerfile を作成し、以下を記述する。
   ※VOLUMEはいらないかもしれない。
   ```Docker
    FROM eclipse-temurin:17-jdk-alpine
    VOLUME /tmp
    COPY target/*.jar app.jar
    EXPOSE 8080
    ENTRYPOINT ["java","-jar","/app.jar"]
   ```
1. Maven でビルド  
    コマンドプロンプトを起動し、Dockerfile が置いてあるフォルダに`cdコマンド`で移動し、以下のコマンドを実行する。
   ```shell
   mvnw install
   ```
   「BUILD SUCCESS」となれば OK。
1. Docker イメージ作成  
   Dockerfile が置いてあるフォルダに`cdコマンド`で移動し、以下のコマンドを実行する。
   ```shell
   docker build -t myorg/myapp .
   ```
1. Docker 実行  
    Dockerfile が置いてあるフォルダに`cdコマンド`で移動し、以下のコマンドを実行する。
   ```shell
   docker run myorg/myapp
   ```
   以下の画面が表示される。
   ![2024-01-03-20-00-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667087/9d682ce4-698f-5bb4-6591-8b3249ad4ecb.png)

1. Hello World 表示
    ブラウザを起動して、以下にアクセスする。
   `http://localhost:8080/helloWorld`
   ![2024-01-03-20-00-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667087/a2b4ea6e-24d9-1b29-a3df-e0011f300240.png)

終わり
WindowsPCにJava17+STS+Mavenの環境を構築する

## WindowsPCにJava17+STS+Mavenの環境を構築する

### 環境情報

- windows10 Enterprise
- JDK 17
- STS 4.21.0
- Maven 3.8.5

### 流れ

1. 環境構築
   1. JDK インストール
   1. Maven インストール
   1. STS インストール
1. HelloWorld 表示
   1. 新規 SpringBoot プロジェクト作成
   1. Controller クラス作成
   1. デバッグ実行
   1. Hello World 表示

### 環境構築手順

1. JDK インストール  
   以下のサイトを参考にインストールする。  
   [OpenJDK 17 のインストールと設定（Windows 上）](https://www.kkaneko.jp/tools/win/openjdk.html)
1. Maven インストール  
   以下のサイトを参考にインストールする。  
   [Apache Maven のインストール手順（Windows 向け）](https://sukkiri.jp/technologies/devtools/maven/apache-maven-installwindows.html)
1. STS インストール  
   以下のサイトでインストーラをダウンロードする。  
   [Spring Tool 4](https://spring.io/tools/)  
   ダウンロードしたjar ファイルを解凍する。インストールはこれで終わり。  
   解凍した「sts-4.x.x.RELEASE」フォルダを選択すると、「SpringToolSuite4.exe」があるので、このファイルを実行すると、STS が起動する。  
1. STS 日本語化
   1. 以下のサイトでインストーラをダウンロードする。  
      [Pleiades プラグイン・ダウンロード](https://willbrains.jp/)
   1. zipファイルを解凍し、setup.exe を実行する。
   1. 日本語化するアプリケーションで「SpringToolSuite4.exe」を選択し、「日本語化する」を押す。
   1. STS を再度起動し、日本語になってることを確認する。

### HelloWorld 表示手順

1. 新規 SpringBoot プロジェクト作成
    新規Springスターター・プロジェクトの作成をクリック。
    ![2024-01-03-19-00-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667087/2f84b0b8-fcc1-a7a2-60bf-068a1309cc9f.png)
    タイプをMavenにして、他はデフォルト。
    ![2024-01-03-19-01-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667087/0bb94170-dd0f-6b17-6bba-63d898b7fa8f.png)    
   簡単な RestAPI を作るだけなので、以下の依存関係だけ。
    ![2024-01-03-19-02-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667087/b140f7d6-85d3-2019-210e-9bd4d367c69f.png)
    ここも特に変更せず。
    ![2024-01-03-19-03-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667087/38c442fa-0c3f-d7cd-7083-0766450b7c95.png)

1. Controller クラス作成
    新しくHelloWorldController.javaを作成し、コード入力。
   ![2024-01-03-19-12-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667087/4cb53eb0-4bf5-dfa4-2d0a-00a135045517.png)
    ```java
    package com.example.demo.helloWorld;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class HelloWorldController {
    
        @RequestMapping("/helloWorld")
        public String home() {
            return "Hello World!";
        }
    
    }
    ```
1. デバッグ実行
    プロジェクトを右クリック>デバッグ>Spring Boot アプリケーションでデバッグ実行
    ![2024-01-03-19-12-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667087/c3086966-e401-e2f9-46bf-664d2261f267.png)
    コンソールに以下が表示される。
    ![2024-01-03-19-13-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667087/68b88dd0-b18b-1141-9769-0aab62a37415.png)
1. Hello World 表示
    ブラウザ立ち上げて以下にアクセス。
   `http://localhost:8080/helloWorld`
    ![2024-01-03-19-14-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667087/497aef81-5f5a-9744-fe3b-3cdad4ad8a84.png)

終わり
VMでWindowsホストにUbuntuをゲスト起動する

6年前にCentOS7.6で構築した検証環境をubuntu22.04.3TLSへ移行するのでメモ

### 環境
仮想化：VMware Workstation-playre17またはVMware workstation-pro17（どちらも確認済み）
ホスト：Windows10またはWindows11pro（どちらも確認済み）
ゲスト：ubuntu22.04.3TLS


### VMware workstation-playre17ダウンロード
[VMware-player-full-17.5.0-22583795.exe](https://www.vmware.com/jp/products/workstation-player/workstation-player-evaluation.html)
※個人利用であれば無償で利用可能

### VMware workstation-pro17ダウンロード（今回こちらを利用）
[VMware-workstation-full-17.5.0-22583795.exe](https://www.vmware.com/jp/products/workstation-pro/workstation-pro-evaluation.html)
30日お試しでDL可能、継続利用の場合ライセンスが必要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340841/b0288ab0-935a-7001-3658-856955ca42c3.png)
ライセンスはインストール時に投入可能、もちろんお試し後でも可

### ubuntu22.04.3TLSダウンロード
[ubuntu-22.04.3-desktop-amd64.iso](https://ubuntu.com/download/desktop)
無償で利用可能

### ubuntu22.04.3TLSインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340841/3f0d50e3-7e9d-625d-e1b7-1d88f28a032b.png)
インストール時、環境に合わせて適宜設定（当方で黄色部分を変えた）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340841/50033a3b-f463-e883-10fe-2353949ef6a3.png)
単一にしても複数に分割してもさほど動作に差がないようなので、そのまま進める

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340841/a3ad6b50-f184-07a3-fbe0-60922ed161b0.png)
そのまま進める

### インストール後に実施
``` sh:パッケージの最新バージョンをインストール
$ sudo apt update
```

``` sh:sshをインストール
$ sudo apt install ssh
```

``` sh:sshのバージョン確認
$ ssh -V
OpenSSH_8.9p1 Ubuntu-3ubuntu0.5, OpenSSL 3.0.2 15 Mar 2022
```
teratermからsshで接続可能を確認

``` sh:ローカルフォルダ確認
$ ls
snap  ダウンロード  テンプレート  デスクトップ  ドキュメント  ビデオ  ピクチャ  ミュージック  公開
```
``` sh:日本語表記を英数表記に変更
$ LANG=C xdg-user-dirs-update --force
$ find . -maxdepth 1 -type d -name '*[ぁ-んァ-ン]*' -exec rm -rf {} +
``` 
※1行目では変更ではなく日本語表記がそのまま残り、英数表記のフォルダが追加になったので次の行で削除している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340841/ba9c4dfa-4afa-41ec-e1b4-def5fb45d283.png)
次に起動したときに図の通り「古い名前のままにする」を選択し「□次回から表示しない」に✔を入れる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340841/b5017113-306d-ca94-39bb-942950304c2c.png)
VMware
編集タブ→仮想ネットワークエディタを開き、ブリッジの自動設定で、ブリッジで利用するホストのネットワークアダプタを選択（デフォルトで全選択される）
当方でブリッジネットワークを3つ作成したがホスト側のWiFi接続以外の2有線IFでゲストとの疎通がうまくいかなかったので実施

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340841/4c07c711-a879-5896-bc7b-53a6098fedb8.png)
2有線IFはDHCPが無いので手動で設定した
※設定後にIFをいったん無効にして再度有効化すること

``` sh:いったんディスク容量を確認（ゲストに40Gを割り当てている状態）
$ df -k
Filesystem     1K-blocks     Used Available Use% Mounted on
tmpfs             396444     1980    394464   1% /run
/dev/sda3       40453376 14888732  23477528  39% /
tmpfs            1982216        0   1982216   0% /dev/shm
tmpfs               5120        4      5116   1% /run/lock
/dev/sda2         524252     6220    518032   2% /boot/efi
tmpfs             396440      128    396312   1% /run/user/1000
``` 

### メモ
■既存で利用中のtetatermでssh接続できない対応
https://qiita.com/tukiyo3/items/b497c3ce285215a9cb02
※この対応をしなくてもteratermを最新化すればssh接続可能

■netstatコマンドができるようにする
sudo apt install net-tools

■設定完了後はいったん再起動し確認する

### 参考にしたページ
https://pepe-log.com/vmware-vmdk-1/
MySQLにおける識別子と予約語

# はじめに
MySQLでテーブルを作成する際に、誤って識別子に予約語を使用してしまったため、構文エラーが発生するという体験をした。
そこで、同じミスを繰り返さないために、MySQLにおける識別子と予約語について知識を整理することにした。

# 識別子とは？
MySQLでは、データベースオブジェクト（データベースやテーブル、カラム）に付ける名前のことを識別子と呼ぶ。

識別子には以下のルールがある。
1. アルファベット（大文字または小文字）、数字、アンダースコア(_)から構成する。
1. 数字から始めることはできない。始める文字はアルファベットまたはアンダースコア(_)でなければならない。
1. 大文字と小文字を区別する。つまり、`MyTable`と`mytable`は異なる識別子と見なされる
1. 最大長は64文字。ただし、実際には使用するデータベースエンジンや設定により異なる場合がある。
1. 識別子がMySQLの`予約語`と一致する場合は、その名前を使用できない。ただし、予約語をバッククォート（`）で囲むことによって、識別子として使用できる。 ※詳細については後述。

# 予約語とは？
予約語は、MySQLが特定の機能や操作を実行するために予め定義しているキーワードである。これらのキーワードはSQL文の構造や動作を定義し、通常、ユーザーがデータベースオブジェクト（データベースやテーブル、カラム）の名前に使用することはできない。予約語はSQLの標準的な構造を維持し、クエリを正しく解釈するために使用される。

予約語は、最新の`MySQL公式ドキュメント`から確認するのがお勧めである。
※将来のバージョンで新しい予約語が導入される可能性があるため。
https://dev.mysql.com/doc/refman/8.0/ja/keywords.html

# 予約語を識別子として使用する場合
予約語をテーブルやカラムなどの識別子として使用する場合、バッククォート(`)で囲む必要がある。例えば、以下のように使用する。

````sql:sql
-- 予約語を識別子として使用する例
CREATE TABLE `select` (
  `from` INT,
  `where` VARCHAR(255)
);
````
上記例では、予約語`select`をテーブルの識別子として使用し、
予約語`from`と`where`をカラムの識別子として使用している。

# まとめ
MySQLでは、予約語を識別子として使用すると構文エラーが発生するが、識別子を`バッククォート`で囲むことによって、この問題を回避できる。

ただし、予約語はMySQLが特定の目的で予め定義しているキーワードであり、識別子として使用する場合は慎重に扱う必要がある。

個人的には、全ての予約語を覚える必要性は感じない（というかできない）が、一度最新のMySQL公式ドキュメントの予約語一覧に目を通し、雰囲気を大雑把にでも掴んでおくのが良いと感じた。
フローを使った一括更新


+ [Do record triggered flows run on multiple records?](https://salesforce.stackexchange.com/questions/328829/do-record-triggered-flows-run-on-multiple-records)

連絡先にレコード トリガー フローがあり、15 件の連絡先が更新されている場合、このレコード トリガー フローは 15 回呼び出されます。Apex トリガーを書く以外にどう進めればよいかわかりません 


それは問題ではないはずです。[トランザクションにおけるフローの一括化に関する記事](https://help.salesforce.com/articleView?id=flow_concepts_bulkification.htm&type=5)を参照してください。

>フローを使用している場合は、バルク化について考える必要さえありません。フロー インタビューでは、アクションが自動的にまとめられます。

追加の読み物

Flow の初期バージョンからの[同様の質問と回答](https://salesforce.stackexchange.com/a/59951/55891)がここにあります。

最後に、数百のレコードを使用した適切なテストを[ここで確認し](https://www.sfdcstop.com/2020/03/are-scheduled-flows-bulkified-lets-find.html)、バルクは 200 レコードのバッチで実行されると結論付けています。

>したがって、スケジュールされたフローは一括化され、200 レコードのバッチでレコードを処理すると結論付けられます。
【Typescript】nullとundefined,anyとunknown

## はじめに
学習の備忘録として残します。
以下について書いています。
・null
・undefined
・any
・unknown

## null と　undefined
### null
値が欠如していることを表す
イメージはトイレットペーパーのホルダー。

### undefined
初期化されておらず値が割り当てられていないことを表す。
できる限りundefinedを使用する
```js
type Hoge = {
  optional?: string; //「?」をつけているので、string | undefinedとして扱われる
  notOptional: string | undefined;
};

const hoge1: Hoge = {
  //「?」をつけていたoptionalプロパティは省略可能
  notOptional: "fuga",
};

const hoge2: Hoge = {
  optional: "fuga",
  notOptional: undefined, //「？」をつけていないので、存在しない場合undefinedを明示する必要がある
};

```

## any と unknown
### any
どんな型でも許容する　→　全く安全ではない。
イメージはメタモン　→　どんなポケモンにも変化できる
```js
const anySample = () => {
  let name: any = "daichi";
  console.log("any sample 1", typeof name, name);
  //any sample 1 string daichi

  name = 23;
  console.log("any sample 2", typeof name, name);
  //any sample 2 number 23
};
```

### unknown
どんな型になるのか不明。
unknownは代入した値によって型が変化する。
イメージはイーブイ → 特定の進化ができる
```js
const unknownSample = () => {
  const maybeNumber: unknown = 10;
  console.log("unknown sample 1", typeof maybeNumber, maybeNumber);
  //unknown sample 1 number 10

  const isFoo = maybeNumber === "foo";
  console.log("unknown sample 2", typeof isFoo, isFoo);
  //unknown sample 2 boolean false

  if (typeof maybeNumber === "number") {
    const sum = maybeNumber + 10;
    console.log("unknown sample 3", typeof sum, sum);
    //unknown sample 3 number 20
  }
};
```

## おわりに
参考の記事が非常によかったです。
何度も確認しようと思います。

## 参考
https://qiita.com/marumaru0113/items/d40ab552d7d699e68a6e
https://typescriptbook.jp/reference/statements/never#never%E3%81%AE%E7%89%B9%E6%80%A7
Field Service トレイルヘッドのまとめ

[FSL(フィールドサービス)のまとめに戻る](https://qiita.com/Keiji_otsubo/items/2b2a47e21d2a489e1391)


+ [Field Service の基本 > Field Service の有効化とサービスリソースの作成](https://qiita.com/Keiji_otsubo/items/43c003c17d1ddc0c2f7e)
+ [Field Service Dispatcher Console for Dispatchers -> Customize Your View](https://qiita.com/Keiji_otsubo/items/df1e26c98b64c905da3d)


# Dispatcher Console for Admins > Add a Custom Action

+ [ディスパッチャ コンソールに表示されるカスタム アクションを取得できないようです](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007SthHw)

https://trailhead.salesforce.com/content/learn/modules/dispatcher-console-for-admins/add-a-custom-action

Field Service 設定のディスパッチャー コンソール UI でガント セクションに新しいアクションを追加すると、使用可能な Apex クラスはウォークスルーのクラスのみになります。。チャレンジ専用に作成された新しいものは表示されません。toggleServiceAppointmentJeopardy は表示されますが、copyAbsenceToNextDay は表示されません。

:::note
 it was really strange - I did have a call with support, and while the action did not show up, in the call I clicked on the "check challenge" and it passed. I still don't know why the action wasn't showing, or HOW it passed, but it did. So if you've completed all of the steps correctly, try checking it anyway.

それは本当に奇妙でした。サポートと電話をかけましたが、アクションは表示されませんでしたが、通話中に「チャレンジの確認」をクリックすると成功しました。なぜアクションが表示されなかったのか、どのようにしてアクションが表示されたのかはまだわかりませんが、表示されました。したがって、すべての手順を正しく完了した場合は、とにかく確認してみてください。
:::

# [フィールド サービス] タブから予定外のサービス予約が表示されないのはなぜですか?

+ [Why can't I see unscheduled service appointments from the Field Service tab?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000HmaVk)

:::note
I think I found it - looks like everything is tied to the dates!  THANKS FOR ALL YOUR ASSISTANCE!!!!

見つけた気がします - すべてが日付に関連付けられているようです! ご協力ありがとうございました！
:::

# Modify the Field Service Center > Create a Work Type

https://trailhead.salesforce.com/content/learn/projects/modify-the-field-service-center/create-a-work-type

+ [While creating a work type. Location type field the picklist value "Space" is not reflecting. As per the trailhead only "Space" should be selected to move foward.](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KCtZM)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/c6c15f20-3f84-20ef-d773-6487344f5b70.png)

:::note
Try adding picklist value 

Goto Setup --> Object Manager -->Location --> Location Field -->Location Type 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/eace8ffb-81e6-2f1d-fafc-a454607e8b43.png)
:::
証明書発行ログによるFQDNバレに注意

# はじめに
- 認証局に発行してもらった証明書の発行状況は簡単に検索できてしまいます。非公表のつもりだったFQDNも，証明書を発行していたらFQDNが簡単にバレます。
- FQDNバレを防ぐため，ステージング用・開発用・テスト用などの公開したくないドメインはプロダクションとは分けましょう。

# まず調べてみる
まず，ご自分が管理または所有するドメインをお持ちであれば，そのドメイン名を下記サイトに入力してみてください。

https://crt.sh

非公表のつもりだったFQDNが表示された方は，そのFQDNの存在は公開されているものと思ってください。

# なぜ公表されているのか
不正な証明書の発行を監視するためです。Wikipediaによれば，[2011年デジノター事件](https://ja.wikipedia.org/wiki/2011%E5%B9%B4%E3%83%87%E3%82%B8%E3%83%8E%E3%82%BF%E3%83%BC%E4%BA%8B%E4%BB%B6)をきっかけに，不正な証明書の発行に対する取組みが始まったそうです。証明書発行の透明性を担保するCT(Certificate Transparency)として，RFC9162に規定されています。

https://jprs.jp/pubcert/about/CT/

# 証明書発行ログとは
RFC9162に規定されています。

## 証明書発行時
認証局が証明書を発行するタイミングで公開ログサーバに仮の証明書を送信してSCTを発行してもらいます。申請者に対して，証明書にSCTを埋め込んで発行します。SCT（Signed Certificate Timestamp）とは，TLS証明書が公開ログサーバに追加されたことを示す署名つきタイムスタンプです。
例えばqiita.comのサーバ証明書を見ると，以下3つのSCTが登録されていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/7b7154f2-485f-71c5-d866-db9e45845508.png)


## 証明書発行後
ブラウザがHTTPSのサイトにアクセスする際に，証明書に記載されたSCTと公開ログサーバの情報を突合し，証明書の正当性を検証します。（Chrome,Edgeは実装していますが，Firefoxは実装していないそうです。そもそもCTの言い出しっぺはGoogleなので，Chrome,Edgeへの実装はむべなるかな）
例えばqiita.comでcrt.shを検索すると以下のように登録されています。おそらく証明書のsha256フィンガープリントとログサーバ上のフィンガープリントなどを比較していると思われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457890/1c4ad1e7-7fbe-5868-01a2-cfa43cb71079.png)


## 公開ログサーバ

以下のサイトで，公式に運用されているログサーバの一覧を確認できます。

https://certificate.transparency.dev/logs/

Chromeが検証している公開ログサーバのURIのリストです。

https://googlechrome.github.io/CertificateTransparency/log_list.html



# 証明書発行ログが公開されていることによるメリット
- 第三者による証明書の発行を検出できる
もし意図せず第三者が証明書を発行していた場合に証明書の検出ができます。もし自分が発行したはずのない証明書が検索結果にあったら，誰かが証明書を不正に取得して悪用しているかもしれません。

# 証明書発行ログが公開されていることによるデメリット
- 証明書を取得したFQDNが公開されてしまう
非公開にしたかったはずのFQDNも例外ではなく，証明書を発行してしまえば検索対象になるのでその存在が明らかになってしまいます。証明書を発行したということは，何らかの形でそのFQDNで証明書を使う予定がある・使っていることを示唆します。例えば，AWS Certificate Managerのようなサービスで一時的にでも証明書を発行した場合にはログに残ってしまいます。

 
# 非公開運用中のドメインの危うさ
悪意のある第三者に非公開前提のFQDNがばれてしまうことで，攻撃の対象とされる恐れがあります。devとかstagingとかtestといった文字列を含むFQDNは，開発用・テスト用であることがあからさまに判別できます。開発用やテスト用のドメインで運用しているサーバやサービスは，（偏見かもしれませんが）プロダクション用と比較してセキュリティ対策が甘いケースがあるようなので注意が必要です。もちろんプロダクション相当の対策を実施していたり，接続元IPアドレス制限をするなどの適切な対処をしていれば攻撃されるリスクは低くなります。

# 証明書発行ログの確認方法
再掲ですが`https://crt.sh`で確認できます。crt.shでは，公開ログサーバに対してまとめてクエリー投げ，その検索結果を表示してくれるようです。

https://crt.sh


# まとめ
- 認証局に発行してもらった証明書の発行状況は簡単に検索できてしまいます。非公表のつもりだったFQDNも，証明書を発行していたらFQDNが簡単にバレます。
- FQDNバレを防ぐため，ステージング用・開発用・テスト用などの公開したくないドメインはプロダクションとは分けましょう。
- 記事の内容が①CTの説明と，②プロダクションとテスト用開発用でFQDNを分けましょう，で多少ごっちゃになってます。タイトルの主旨的には②がメインです。