OmniAICreator/Qiita-1.07M huggingface dataset:
TLSフィンガープリントとは

## 概要

TLSネゴシエーションには個々のクライアントごとにパラメータ等の十分な違いがあり、それらをハッシュ化して識別しようというもの。2015年頃に発表された研究が基礎になっているらしい。

フィンガープリント・・・指紋
なのでTLS接続を利用して採取する接続元クライアントの指紋、のようなイメージ。

IPブラックリストと同様にWAFに設定して利用するのが主流と思われる。

## TLSとは
インターネットを経由するクライアントとサーバー間の通信を暗号化するためのプロトコル。SSLが進化してTLS。SSL/TLSとも呼ばれる。

セキュリティ的な観点では、SSL1.0/2.0/3.0及びTLS1.0/1.1には脆弱性が存在していることから現在は非推奨である。TLS1.2か1.3を使うのが一般的（2024年8月現在）


## TLSフィンガープリントの取得
代表手法であるJA3について記述する。

TLSを用いた通信では、まずクライアントとサーバー間で暗号化のための「共通鍵」を交換しなければならない。この手順を、TLSハンドシェイクと呼ぶ。


:::note
TLSハンドシェイクは鍵交換の流れ全体を指すのに対し、TLSネゴシエーションは暗号アルゴリズム選択のステップに焦点をあてたものを指す。
:::

```plantuml
Client->Server : Client Hello
Client<-Server :・・・
```
TLSハンドシェイクは、クライアントからサーバーへの通信（Client Hello）から始まる。
SSL/TLS通信を開始するため、以下の情報をサーバーへ伝える。
- SSL/TLSのバージョン
- 受け入れられる暗号（暗号スイート）
- 拡張リスト
- サポートされるグループ
- 楕円曲線フォーマット
など

これらの情報はブラウザの実装に大きく依存しており、クライアントごとに固有のパラメータとなりやすい。そのためアクセスしてきたクライアントのパケット（Client Hello）を観測し、これらの情報をハッシュ化したものがTLSフィンガープリントとなる。

具体的な手順としては、下記の通り。

1. それぞれの情報のバイト列を10進数に変換
1. 10進数文字列を連結
1. 連結文字列をMD5でハッシュ化
<br>
ちなみにMD5は脆弱なハッシュ関数として知られているが、目的が暗号化ではないため問題ないのだと思う。反対にコンパクトな形式であることから検索性の向上にも繋がるらしい。




## 誤検知について
TLSフィンガープリントの特徴として、誤検知の可能性が挙げられる。

接続元クライアントの識別方法としてはグローバルIPアドレスが最も一般的であるが、TLSフィンガープリントを利用した場合、正規のユーザーが攻撃者と同じ（あるいは似ている）動きをみせた場合に誤検知の可能性が生じる。
裏を返せば、攻撃者が正規のユーザーに似せた動きを取ることで検知を回避できてしまうことになる。

TLSフィンガープリントを利用したブラックリストを有効化する際は上記に注意が必要。



## 所感
IPアドレスをコロコロ変えるように、攻撃者もTLSネゴシエーションのパラメータを変更すれば異なるフィンガープリントを装えるため、結局イタチごっこにはなりそう。
ただTLSネゴシエーションを偽装させる手前をかける、という意味では効果はあるのかもしれない。

<br>
以上

## 参考文献
以下の情報を参考とさせていただきました。

https://www.fastly.com/jp/blog/the-state-of-tls-fingerprinting-whats-working-what-isnt-and-whats-next/

https://lab.iisec.ac.jp/~okubo_lab/docs/browser_tls_fingerprint.pdf

https://www.infraexpert.com/study/security28.html
Paiza×Qiitaキャンペーン Javaで解説してみた【C みかんの仕分け 編】

# 問題へのリンク

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/mikan

# 解答コード

<details><summary>詳細</summary>

~~~

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);

		final int N = scanner.nextInt();
		final int M = scanner.nextInt();

		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < M; i++) {
			final int W = scanner.nextInt();

			int quotinent = W / N;
			int remainder = W % N;

			if (quotinent == 0 || remainder * 2 >= N) {
				quotinent++;
			}

			sb.append(quotinent * N).append("\n");
		}

		System.out.println(sb);
		scanner.close();
	}
}

~~~

</details>

# 解説

<details><summary>詳細</summary>

Wを一度Nで割った商によって箱分け、余りで前後の箱の細かな振り分けをするといいでしょう。

ただ、間違いやすいポイントが多い問題です。
・0のBOXが無い　⇒　商=0の時は強制切り上げ
・N = 偶数の時 : 大きな箱と小さな箱、等距離なら大きい箱　⇒　>= と >の間違い
・N = 奇数の時 : Nを2で割ると端数切捨ててしまう ⇒ Nを割るのではなく余りを倍にする

</details>
【Unity】カメラの画面描画範囲をUIに合わせる


## 概要

オーバーレイ UI に合わせてカメラの画面描画範囲を制御したい

## 結論

カメラの Viewport 値を設定することで実現できる．UI (RectTransform) から取得した Viewport 領域をカメラに設定する．

## 詳細

#### RectTransform から viewport 値を取得する

ビューポート座標は画面左下を ( x, y ) = ( 0, 0 )、 画面右上を ( x, y ) = ( 1, 1 ) とした座標値．
RectTransform.GetWorldCorners()で四隅のワールド座標が取得できるので、これと画面サイズからビューポート座標を計算する．

※もし Overlay 以外の RenderMode に対応したい場合、GraphicRaycaster.cs の Raycast()の実装が参考になる

![20240821_Rect_Viewport.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1596227/2334b89c-d61b-98de-3af4-6c16ed2d49c6.gif)

【参考】

https://light11.hatenadiary.com/entry/2019/04/24/232041

#### カメラの viewport 値に設定する

Camera.rect に要素の値域が 0~1 の Rect を代入することで、viewport 設定が行える．

```.cs
// ビューポート値を計算 (※canvasはOverlayを想定)
var viewportRect = RectTransform.GetViewportRect();

// カメラのプロパティに設定する
Camera.rect = viewportRect;
```

インスペクタでの以下に対応している（※画像は URP の場合）
<img width="50%" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1596227/08d77485-ad2a-a6f5-a592-a414ddf37fb1.png">

(X,Y) = (0,0) / (W,H) = (1,1) の場合
<img width="70%" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1596227/6f08b42c-7a9e-4072-bb07-898356575b05.png">

(X,Y) = (0.2,0.1) / (W,H) = (0.7,0.5) の場合
<img width="70%" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1596227/eafb80cf-00e6-c310-1142-70d1c2df48d8.png">

【注意点】
アクティブなカメラが一つのみの場合、Viewport を変更した際にカメラの非描画領域(ビューポート外)の画面ピクセルがクリアされないという問題が発生した．（※エディタモードのときはバッファがクリアされる）

対策として背景描画用のカメラ（CullingMask = nothing, Priority = -10）を配置して、画面の描画を行うようにした．
入力された項目のみ検索条件とする（where句で実現）

### 想定されるケース
一覧画面で検索項目が複数あるが、値が入力された項目についてのみ検索条件で使用されるようにする。

### 例
以下3項目で検索できる画面とする
・商品名
・値段
・ブランド名

### 実装
画面で選択された項目のみ検索されるようにするには、
(A is null OR A = [入力値])といった条件で実現する。

```ｒ.sql
select ProductName, /* 商品名 */
       Price,       /* 値段 */
       BrandName    /* ブランド名 */
from TABLE 
where 1=1
  and ([:商品名] is null OR ([:商品名] is not null AND ProductName = [:商品名])
  and ([:値段] is null OR ([:値段] is not null AND Price = [:値段])
  and ([:ブランド名] is null OR ([:ブランド名] is not null AND BrandName = [:ブランド名])
  ```
ACCESSでクエリのSQLパラメータにフォームで入力した値をつかいたい（VB無しで動的なクエリ）

# フォームの値をクエリに連動させる手順
- フォームを作成する:

値を入力するためのフォームを作成します。フォームにテキストボックス、コンボボックス、またはその他のコントロールを配置します。
- クエリを作成する:

クエリデザインビューでクエリを作成します。
クエリの条件フィールドで、フォームのコントロールの値を参照します。
フォームのコントロールをクエリに参照する:

- クエリの条件行に以下のように記述します：
```
[Forms]![フォーム名]![コントロール名]
```
例えば、「CustomerForm」という名前のフォームに「CustomerID」というテキストボックスがあり、その値をクエリの条件にしたい場合は、次のようにします：
```
[Forms]![CustomerForm]![CustomerID]
```
- クエリを実行する:

フォームに値を入力し、クエリを実行すると、入力した値に基づいた結果が表示されます。

:::note warn
注意点
クエリを実行する際には、フォームが開いている状態でなければなりません。
フォームの値が空の場合、クエリの結果が意図しないものになる可能性があります。必要に応じて、クエリの条件に「Nullチェック」を追加することを検討してください。
:::
【無課金】Adobe Expressが背景削除に有能だった話

## これは何?

最近デスティニーガンダム spec2のメタルロボット魂が来たのですが，背景がお家の壁だとどうも写真が映えないので背景を合成するためにAdobe Expressを使ってみたらいい感じに切り抜けました。

こちらが元画像になります。
![destiny.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718390/b55008d3-f3f5-91fb-b921-649cf2f8a4d7.png)


## Adobe Expressを試してみた感想
- [Adobe Express](https://www.adobe.com/jp/express/feature/image/remove-background)にアクセスして画像アップロードするだけで切り抜いてくれます。

手軽な割に結構精度が良かったです。出来上がりはこんな感じ↓
![file.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718390/d89bbc19-110b-8e4d-07a8-cab723cf11e3.png)

一部のビームエフェクトと台座部分までは流石にくり抜けませんでしたが，必要な部分が消えてしまうということはありませんでした。素晴らしい✨

最後にGimpで台座とビームエフェクトの穴抜きをして劇中背景を合成したらいい感じになりました。
これが人の夢！ 人の望み！
みなさんも背景だけが微妙な写真は背景削除して合成すると楽しいと思います。

![分身はこうやるんだ!!.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718390/f001b62d-6bf5-400c-2d07-431c4216c049.png)
GitHubの100MB制限とLFS対象をコミット時点で弾きたい

# あっ、いつの間にかGitHubの容量制限に！！
…のようなケアレスミス憤死を防ぐための転ばぬ先の杖的なスクリプトを用意しました。が、調査が足りず作る必要のない実装してしまい、いわゆる車輪の再発明をしていました。

# 車輪の再発明
私はよくUnityを使うので100MBを超えるFBXファイルだのメディアファイルだのをコミットしてよくリポジトリを詰まらせています。なのでまず事故防止に自分用のスクリプトを作りました。

```sh:pre-commit
#!/bin/bash

MAX_SIZE=$((100 * 1024 * 1024)) # 100MB in bytes
all_files_ok=true

lfs_files=$(git lfs ls-files -n)

for file in $(git diff --cached --name-only)
do
    if [ -f "$file" ]; then
        if echo "$lfs_files" | grep -q "^$file$"; then
            echo "Info: $file is managed by LFS. Skipping size check."
            continue
        fi

        file_size=$(stat -c%s "$file")
        if [ "$file_size" -gt "$MAX_SIZE" ]; then
            echo "Error: $file is larger than 100MB ($(du -h "$file" | cut -f1))."
            all_files_ok=false
        fi
    fi
done

if [ "$all_files_ok" = false ]; then
    exit 1
fi

exit 0
```
これが車輪の再発明です。
check-added-large-filesを使えば良いので
以下のように設定したらおしまいです。

```sh:.pre-commit-config.yaml
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0  # 最新バージョンに合わせてください
    hooks:
      - id: check-added-large-files
        args: ["--maxkb=102400"]  # 100MBをKBで指定
```
ただし、これを導入するためにはGit環境中でパッケージマネージャーが存在することが前提です。
例えば素のWindowsにはないのでこれだけのためであればpre-commitファイルを書く方がいいし、
非エンジニアにやらせる場合も「このファイルをここに入れてね」で話が済みます。

pre-commitについてはこちらも参考にしていただけると。
https://qiita.com/raki/items/5374a91dca4a3039094b

コメントでの指摘に感謝します。
コンテナ（フロントエンド、バックエンド）間での通信設定

■From
コンテナ上のフロントエンド（例:Next.js）
■To
コンテナ上のバックエンド（例:djangoのapi） 

上記From→ToへAPI通信を行う際は、
フロントエンド側のnext.config.mjsにて、docker.internalの設定を行う。


```next.config.mjs
const nextConfig = {};
export default {
    async rewrites() {
        return [
            {
                source: '/api/:path*',
                destination: 'http://host.docker.internal:8000/api/:path*/',
            }
        ]
    }
};
```
ACCESS VBAでエクスポート操作の出力先パスを変更する（エクスポート定義ではない）

# ACCESS VBAで既存のエクスポート操作を使いたい場面で出力先の設定に苦戦したのでメモ

元の定義で``<ImportExportSpecification Path="ここにパス" xmlns="urn:www.microsoft.com/office/access/imexspec">``のようになっている場合以下のようにすると出力先パスを変更してエクスポート操作を指定できます。
・定義XMLの中身を確認するにはstrXML = Obj.XMLのところをデバッグ
・パスの指定箇所が上述のものと異なる構造な場合は``prefix = ``、``newLine = ``の箇所を修正

```
Function main()
        Dim Prj As CodeProject
        Dim Obj As ImportExportSpecification
        Dim strExportName  As String
        strExportName = "エクスポート操作の名前"
        Set Prj = CurrentProject
        
        ' XMLで定義を取得する
        Set Obj = Prj.ImportExportSpecifications(strExportName)
        strXML = Obj.XML
        strXML = ProcessLines(strXML, "ここに新しい出力先")
        ' 変更後のXMLを適用
        Obj.XML = strXML

        ' エクスポート操作の実行
        DoCmd.RunSavedImportExport strExportName

End Function

' エクスポート操作の一部変更用
Function ProcessLines(str As String, newPath As String) As String
    Dim str2 As String
    Dim lines() As String
    Dim i As Integer
    Dim prefix As String
    Dim newLine As String

    ProcessLines = ""
    str2 = ""
    prefix = "<ImportExportSpecification"
    newLine = "<ImportExportSpecification Path=""" & newPath & """ xmlns=""urn:www.microsoft.com/office/access/imexspec"">"

    ' 文字列を改行で分割
    lines = Split(str, vbCrLf)

    ' 各行を処理
    For i = LBound(lines) To UBound(lines)
        ' 各行を表示 (ここで必要な処理を行う)
        ' Debug.Print (i) & ":" & lines(i)
        '     文字列前方一致確認
        If (Left(lines(i), Len(prefix)) = prefix) Then
            ' Debug.Print "変換"
            str2 = str2 & newLine & vbCrLf
        Else
            str2 = str2 & lines(i) & vbCrLf
        End If
    Next i
    ProcessLines = str2
End Function
```

無理やり感がありますが、もっとスマートな方法があれば教えていただけると嬉しいです。
SessionStorage、LocalStorage、Cookiesの違いと使い分け - 備忘録

## はじめに

Webアプリケーションを開発する際、クライアント側にデータを保存する方法として「SessionStorage」「LocalStorage」「Cookies」の3つがよく使われます。それぞれの特徴や違いを理解し、適切に使い分けることで、アプリケーションの性能やセキュリティを最適化することができます。ここでは、これら3つのストレージの違いや、実際の利用シーンについて備忘録としてまとめてみました。

## SessionStorage

### 概要
- **保存期間**: ブラウザのタブが閉じられるまで
- **容量**: 約5MB
- **スコープ**: オリジン（ドメイン + プロトコル + ポート）
- **セキュリティ**: JavaScriptからアクセス可能

### 特徴
SessionStorageは、特定のタブで開いている間だけデータを保持します。タブを閉じるとデータは自動的に削除されるため、一時的なデータ保存に適しています。

### 利用例
- **一時的なユーザー入力の保存**: ユーザーがフォームを途中まで入力したが、ページ遷移やタブの操作が行われた場合でも入力データを保持しておきたい場合に利用します。
- **ステップごとのデータ保存**: 複数ステップにわたるフォームなどで、ユーザーが各ステップごとに入力したデータを保存しておく場合。

```javascript
// データの保存
sessionStorage.setItem('key', 'value');

// データの取得
const value = sessionStorage.getItem('key');

// データの削除
sessionStorage.removeItem('key');
```

## LocalStorage

### 概要
- **保存期間**: 永続的（ユーザーが削除するまで）
- **容量**: 約5MB
- **スコープ**: オリジン（ドメイン + プロトコル + ポート）
- **セキュリティ**: JavaScriptからアクセス可能

### 特徴
LocalStorageは、ユーザーが手動でデータを削除しない限り、永続的にデータを保存します。容量がSessionStorageやCookiesに比べて大きいため、アプリケーション設定やユーザーのカスタマイズデータなど、長期間にわたって利用するデータの保存に適しています。

### 利用例
- **ユーザー設定の保存**: ダークモード設定や表示言語設定など、ユーザーが再度アクセスしたときに同じ状態を維持したい場合。
- **アプリケーションのキャッシュ**: オフライン時にアプリケーションを利用できるように、データをキャッシュとして保存する場合。

```javascript
// データの保存
localStorage.setItem('key', 'value');

// データの取得
const value = localStorage.getItem('key');

// データの削除
localStorage.removeItem('key');
```

## Cookies

### 概要
- **保存期間**: 開発者が指定（セッション終了、または指定された期間）
- **容量**: 約4KB
- **スコープ**: ドメインとパスで制御可能
- **セキュリティ**: HTTPOnlyオプションを使用することでJavaScriptからのアクセスを制限可能

### 特徴
Cookiesは、主にサーバーとクライアント間でのデータのやり取りに使用されます。HTTPリクエストごとに自動的に送信されるため、セッション管理やユーザー追跡に便利です。ただし、容量が非常に小さいため、少量のデータの保存に適しています。

### 利用例
- **セッション管理**: ログイン状態を維持するためのセッションIDを保存する場合。
- **トラッキング**: ユーザーのサイト訪問履歴をトラッキングするためのIDを保存する場合。

```javascript
// Cookiesの設定
document.cookie = "username=John Doe; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/";

// Cookiesの取得
const cookies = document.cookie;

// Cookiesの削除
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
```

## まとめ

| 特徴              | SessionStorage               | LocalStorage                 | Cookies                       |
|------------------|------------------------------|------------------------------|-------------------------------|
| 保存期間          | タブが閉じるまで              | ユーザーが削除するまで        | 指定された期間またはセッション |
| 容量              | 約5MB                         | 約5MB                         | 約4KB                          |
| セキュリティ       | JavaScriptからアクセス可能     | JavaScriptからアクセス可能     | HTTPOnlyオプションでJavaScriptアクセス制限可能 |
| 利用例            | 一時的なデータ保存            | 長期間のデータ保存            | セッション管理、トラッキング  |

それぞれの特性を理解し、適切なシーンで使い分けることが、Webアプリケーションのパフォーマンスやセキュリティを向上させるために重要と思われる。
大きなテーブルと小さなテーブルを効率よく結合する(SPSS Modeler データ加工逆引き6-16)

# 大きなテーブルと小さなテーブルを効率よく結合する

![スクリーンショット 2024-08-15 14.10.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/1239e8a1-4f48-37c5-b11c-c0fa38792c74.png)

## 1.想定される利用目的

・なるべく高速に大きなテーブルを結合する（CSVなどのフラットファイルを想定）

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/raw/main/large_small.str

## 3.サンプルストリームの説明

![スクリーンショット 2024-08-15 14.12.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/24415d50-6dce-9d5c-0283-fd6ed5189e1d.png)

a.入力するデータのひとつめは以下の通りです。278万行の大規模なテーブルです。
![スクリーンショット 2024-08-15 16.54.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/3289ca12-5861-ad5e-5ff0-c0eff1f7cbbe.png)

b.入力するデータふたつめは以下の通りです。7行のマスタテーブルです。
![スクリーンショット 2024-08-15 16.54.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/5712b1dd-064f-864d-f0ce-2cc550ba836c.png)

c.[レコード結合]ノードを編集します。曜日番号をキーにします。
![スクリーンショット 2024-08-15 16.54.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/7a742283-7035-7389-fe1f-084e1dd6db50.png)

効率的に結合させるため[最適化]タブで大規模データの選択を行います。
![スクリーンショット 2024-08-15 16.54.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/134028a9-1120-beca-d2e0-26e36a5ecd31.png)

[テーブル]を実行します。
![スクリーンショット 2024-08-15 16.55.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/286daeb4-06b7-164f-738b-6e0a195ff630.png)


サンプルストリームを最初に実行するとパターン３のキャッシュなしが該当します。
![スクリーンショット 2024-08-15 17.00.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/e365b7ca-673b-8cb3-0db1-9271e8d3dea0.png)

キャッシュのバッジがグリーンに点灯した状態で再度[テーブル]を実行するとパターン4になります。11秒であったため、「最適化なし」のパターン２と比較しても半分のスピードで結合が終了したことになります。

![スクリーンショット 2024-08-15 16.55.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/52f4d612-42e8-9b35-1c4c-250824f9165f.png)

キャッシュの説明はこちらを参照してください。

https://qiita.com/416nishimaki/items/1755c4107105e8bdfe90


#### 注意事項

今回はフラットファイルのためにキャッシュを利用しましたが、DB接続のケースではキャッシュを外してSQLプッシュバックを想定した工夫を検討します。例えばDBによってはあらかじめテーブルサイズの統計を取ることで、今回と同じようように効率化を実現できます。

https://qiita.com/416nishimaki/items/48bf0176afae916de117

## 4.参考情報

#### レコード結合を解説した記事

https://qiita.com/416nishimaki/items/be61a82c12cd83558def

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
Lodashでkintoneを意識しつつデータを操作する

# lodash

https://www.npmjs.com/package/lodash

lodashはJavScriptのユーティリティーライブラリです。kintoneカスタマイズでは大変便利なライブラリです。
"_"がグローバルオブジェクトで出てきたときは、lodashが利用されています。


# _.isEmpty(str)
kintone開発ではおそらく一番利用される関数です。これは値の空を確認する関数で、フィールドに値が存在するかどうかを検査するときにつかいます。

```javascript
const dropdownValue = ev.record.ドロップダウン.value;
if(_.isEmpty(dropdownValue)){
    ev.record.文字列一行.value = dropdownValue
}
```

_.isEmptyで書かない場合は以下のように書く必要があります。

```javascript
null != dropdownValue || '' != drowdownValue
```
👇kintoneのドキュメントからの抜粋。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712902/161df172-ce12-6897-50e4-5800beb9ed23.png)

検査に"==="を使うと不具合を起こしやすいのも特徴です。(nullとundefinedを両方意識する必要がある。）

_.isEmptyは、配列の空も検査できるため、チェックボックスでも同じように利用することができます。

---

空値のチェックはとにかくバグを埋め込みやすいので、ぼくはlodashで書く癖をつけています。

# _.range(start, end, step=1)
startからstepずつ加算していき、**end未満**までの数値を格納した配列を返します。
stepの初期値は1。

10~20までの偶数値をサブテーブルに入れたい場合は以下のように書きます。
```javascript
const rec = kintone.app.record.get();
rec.record.テーブル.value = _.range(10, 21, 2) //[10,12,...,20]
    .map(num => {
        const subtableItem = {
            数値 : {
                value : num,
                type : "NUMBER"
            }
        }
        return {
            value : subtableItem
        }
    });
kintone.app.record.set(rec);
```

# _.uniq(array)
逆にテーブルやレコードに複数の値が入っていて、重複を排除したい場合に利用します。
サブテーブルに入っているメールアドレスを文字列複数行に改行で区切って設置してみます。
```javascript
const rec = kintone.app.record.get();

//【メールアドレス】というフィールドの値を配列にして取り出す。
const customerEmails = rec.record.顧客リスト.value.map((subtableRow) => {
    const subtableItem = subtableRow.value;
    return subtableItem.メールアドレス.value
})
.filter(
    //空値を排除
    mail => !_.isEmpty(mail)
);


const customerEmailsUnique = _.uniq(customerEmails);

//【メール一覧】は文字列複数行。メールアドレスごとに改行して配置
rec.record.メール一覧.value = customerEmailsUnique.join('\n')

kintone.app.record.set(rec);
```

# _.chunk(array, size=1)
配列をsizeに示される要素数で切り出します。sizeの初期値は1。
kintoneでは登録/更新は100件ずつしかできませんので、よく使いますね。
```javascript
const nums = _.range(1, 2001, 1);//[1,2,3,4...2000]

const chunks = _.chunk(nums, 100); //[[1,2...], [101, 102...], [201...]...]

const appId = `222`;
const body = {
    requests : chunks.map((numArray /* [1,2...100] */) => {
        return {
            method : 'POST',
            api : `/k/v1/records.json`,
            payload : {
                app : appId,
                records : numArray.map((num /* 1 */) => {
                    return {
                        連番 : { value : num}
                    }
                })
            }
        }
    })
};

//kintoneのREST APIでのデータ登録は100件ずつしかできない。
await kintone.api(kintone.api.url('/k/v1/bulkRequest.json', true), 'POST', body);
```

# まとめ
lodashは開発で必須のライブラリなので、うまく使えるとうれしいですね！
_.sampleなんかもよく使う関数です。まだ知らない関数があるかもしれない。
おすすめの使い方がありましたら、教えてください😊

---

https://www.pulsar-works.jp/

kintoneのプラグイン開発や研修などを行っています。
お仕事のお話はこちらまで。
@capacitor/preferencesでJSONを保存する際の注意点

preferencesAPIは、軽量なデータを入れるためのkey, valueストアです。

で、JSONをそのまま入れるときの注意点なんですが、Date型を入れたあと、もとに戻す際にzodでparseすると失敗します。でもなぜかエラーが出ませんでした。これに気づかずに全然データが取得できず、時間を3時間くらい溶かしました。

以前にもtanstack queryでDATE型をやり取りしようとしてハマったことがありました。同じ轍を踏んでしまったわけです。DATE型のあるオブジェクトをJSONにしてなんだかんだしたいときは注意が必要ですね……。
SQLServer IDENTITY カラムにデータを指定してインサートする方法

# テーブル定義
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/93af9ed7-2cb9-29b2-0cdf-8c933022c615.png)

# Insert SQL
```
SET IDENTITY_INSERT dbo.test ON; 
INSERT INTO  dbo.test (ID,start_date,end_date) VALUES (15,'2024/01/09' ,'2024/07/18');
```
# 参照サイト
https://learn.microsoft.com/ja-jp/sql/t-sql/statements/set-identity-insert-transact-sql?view=sql-server-ver16
WioLTE: Hello World

## プログラム

```text:hello_world/hello_world.ino
// ---------------------------------------------------------------------
/*
	hello_world.ino

						Aug/21/2024
*/
// ---------------------------------------------------------------------
#define	PROGRAM	"hellow_world.ino"
#define	VERSION	"2024-8-21 PM 12:38"

int count = 0;
void setup()
{
	SerialUSB.println("*** start ***");
	SerialUSB.println(PROGRAM);
	SerialUSB.println(VERSION);
	delay(1000);
	SerialUSB.println("*** setup end ***");
	delay(1000);
}

// ---------------------------------------------------------------------
void loop() 
{
	SerialUSB.println(PROGRAM);
	SerialUSB.println(VERSION);
	SerialUSB.println("Hello World! " + String(count));
	delay(1000);
	SerialUSB.println("Good Morning! " + String(count));
	delay(1000);
	SerialUSB.println("こんにちは " + String(count));
	SerialUSB.println();
	delay(3000);
	count++;
}

// ---------------------------------------------------------------------
```

## Arduino IDE

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/a251f284-91be-5004-e149-37ef9374f182.png)
UE5でPackage化したappのログ出力先(mac m1)

macでUEの開発をして、app化した際にログの場所がわからなかったので、メモ。

# 最終的なログのパス

```
/Users/[ユーザー名]/Library/Containers/com.YourCompany.[プロジェクト名]/Data/Library/Logs/[プロジェクト名]
```

# パスの探し方(Blueprint)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2915/b6441bee-87ee-3a25-f720-43a6690994a9.png)
同期処理と非同期処理

## 同期処理（Synchronous）

同期処理は、あるタスクが完了するまで次のタスクに進めない処理のことです。

### 特徴

- **順番に実行**：タスクは順番に実行され、前のタスクが完了しないと次のタスクは開始されない
- **シンプル**：処理の流れが分かりやすく、デバッグが容易
- **ブロッキング**：処理が完了するまで他の処理がブロックされる

### 例

- 料理：鍋に水を入れ、火をつけて沸騰させる。水が沸騰するまで次の作業に進めない
- プログラム：計算結果を得るために、計算処理が完了するまで次の処理に進めない

## 非同期処理（Asynchronous）

非同期処理は、あるタスクを開始した後、その完了を待たずに次のタスクに進める処理のことです。

### 特徴

- **並行実行**：複数のタスクを並行して実行できる
- **応答性**：ユーザーからの入力にすぐに反応できる
- **複雑**：処理の流れが複雑になり、デバッグが難しくなる場合もある

### 例

- 料理：鍋に水を入れ、火をつける。水が沸騰している間に、野菜を切るなどの別の作業を行う
- プログラム：Webサーバーからデータを取得する処理を開始し、その間に画面表示などの他の処理を行う

## なぜ非同期処理が必要なのか？

- **ユーザー体験の向上**：非同期処理により、ユーザーは待たされることなく、スムーズにアプリケーションを利用できる
- **パフォーマンスの向上**：複数のタスクを並行して実行することで、処理時間を短縮できる
- **I/Oバウンドな処理**：ファイルの読み書きやネットワーク通信など、I/O処理に時間がかかる場合は、非同期処理が効果的

## 同期処理と非同期処理の使い分け

- 処理の流れが単純で、順番に実行する必要がある場合：同期処理
- 複数のタスクを並行して実行したい場合、またはI/Oバウンドな処理がある場合：非同期処理

## JavaScriptにおける非同期処理

JavaScriptでは、主に以下の方法で非同期処理を実現できます。

- **コールバック関数**：関数の引数に別の関数を渡すことで、非同期処理の完了後に実行する処理を指定する
- **Promise**：非同期処理の結果を表現するオブジェクト
- **async/await**：Promiseをより同期的に記述するための構文
OCI Cost Analysis(コスト分析)

OCI(Oracle Cloud Infrastructure)にはお客様がコスト管理をするために無料で利用できる標準サービスが提供されており、順次紹介していきます。今回は第５回 OCI Cost Analysysです。

第１回　OCI FinOps Hub
https://qiita.com/nsaka0315/items/e645bb0114e8e9a19dc4
第２回　OCI Cloud Advisor
https://qiita.com/nsaka0315/items/73906772854b675e11d5
第３回　OCI Bugedts
https://qiita.com/nsaka0315/items/460dd316defabdc0fc2b
第４回　OCI Cost&Usage Report
https://qiita.com/nsaka0315/items/d1faba63218596d8982b
第５回　OCI Cost Analysys(本稿)

## コスト分析
コスト分析は、Oracle Cloud Infrastructureの費用支出の管理および最適化に役立つ、使いやすいビジュアライゼーション・ツールです。Oracle Cloud Infrastructureのリソースの利用費用/使用量に関して様々な視点からの集計・分析、グラフ・表での表示が可能です。

コスト分析を使用するには、テナンシ(ルート・コンパートメント)のusage-reportを使用できるIAM権限が必要です。
```
Allow group <group_name> to read usage-report in tenancy
```
後ほど説明する「新規レポートとして保存」の機能を使用するには、次のポリシー・ステートメントが必要です
```
Allow group <group_name> to manage usage-report in tenancy
```

さて次に実際のOCI管理画面を見ていきましょう。
OCI管理コンソールの左上のハンバーガーメニューより「請求とコスト管理」-「コスト管理」-「コスト分析」をクリックします。
「コスト分析」ページが最初に開いたときに「サービス別コスト」レポートが表示されます。開始日/終了日、粒度(毎日/毎月)、表示(コスト/使用量)を選択します、
「フィルタ」メニューを使用して、特定のタグ、コンパートメント、サービス等により抽出条件を指定、「グループ化ディメンション」メニューを使用して、どのようにグループ化するかを選択し適用することにより、チャートおよび対応する詳細データ表が生成されます。「新規レポートとして保存」ボタンを押し名前を指定して保存すれば、次回から保存したレポート名を選択することで選択条件を再指定することなくレポートの作成ができます。保存したレポートは、後で名前変更、更新または削除できます。また「レポートアクション」ボタンを押すことでCSVファイル、PDFまたはチャート・イメージとしてダウンロードすることもできます。

![スクリーンショット 2024-07-31 10.48.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849840/301a4b84-a02e-0fa0-63db-783aa6bb680b.png)

コスト分析を使用すると、過去の使用状況データに基づいて、将来のCloud利用費用および使用量の情報を見積ることができます。
「コスト分析」画面から「予測の表示」チェックボックスにチェックをいれ、予測期間を指定して、「適用」をクリックすればチャートに予測データがリロードされます。予測には指数平滑法(時系列データから将来予測する標準的な統計手法)が使用されます、「毎日」粒度で予測を行うには少なくとも10日間の履歴データが、「毎月」粒度で予測を行うには、少なくとも3か月間の履歴データが必要です。

下記画面の詳細データ表では予測データはブルーで表示されています。
![スクリーンショット 2024-07-31 10.49.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849840/e59ed531-3bea-5bd4-09dd-7632ee02e570.png)

## スケジュール済みレポート機能
上記のコスト分析から保存されたレポートを使用してスケジュール済みレポートを生成します。これを使えば都度OCIコンソールにログインしてコスト分析画面からレポートをダウンロードしなくても、定期的に自分の欲しい形式でObject Storageにレポートを出力・保存しておくことが可能です。

OCI管理コンソールの左上のハンバーガーメニューより「請求とコスト管理」-「コスト管理」-「スケジュール済みレポート」を選択します。
スケジュール済レポートの作成ボタンを押して、入力画面より「保存されたレポート」のフィールドに上記コスト分析画面で保存されたレポート名を指定して「開始日」と「反復」を入力して、「バケット」には事前に作成しておいたObjectStorageのBucket名を指定して作成ボタンを押します。
これでコスト分析レポートが定期的にObject Storageに出力されます。

![スクリーンショット 2024-08-14 11.36.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849840/3705a2f4-289c-f8bd-1276-623caae7ecfc.png)

### 参考情報
[OCIドキュメント コスト分析](https://docs.oracle.com/ja-jp/iaas/Content/Billing/Concepts/costanalysisoverview.htm)
OCI Cost&Usage Report(コスト・使用状況リポート）

## コスト及び使用状況レポート
OCI(Oracle Cloud Infrastructure)にはお客様がコスト管理をするために無料で利用できる標準サービスが提供されており、順次紹介していきます。今回は第４回　OCI Cost&Usage Reportです。

第１回　OCI FinOps Hub
https://qiita.com/nsaka0315/items/e645bb0114e8e9a19dc4
第２回　OCI Cloud Advisor
https://qiita.com/nsaka0315/items/73906772854b675e11d5
第３回　OCI Bugedts
https://qiita.com/nsaka0315/items/460dd316defabdc0fc2b
第４回　OCI Cost&Usage Report(本稿)
第５回　OCI Cost Analysys 
https://qiita.com/nsaka0315/items/61b65a1bc3ae7805a32f

「コストおよび使用状況レポート」は、OCIリソースの利用コストを示すコスト・レポートと消費されたリソースの利用量を示す使用状況レポートをダウンロードできます。
コスト分析でも利用コスト/利用量を見ることはできるのですが、「コストおよび使用状況レポート」は時間単位のより詳細な情報を取得できます。
コスト及び使用状況レポートで出力されるCSVファイルはOracle所有のオブジェクト・ストレージ・バケットに格納されます。CSV(カンマ区切り値)ファイルには、１時間単位でOCIリソースID(ocid)ごとに、使用量(usage/billedQuantity)、コスト(cost/myCost)、価格(cost/unitPrice)、タグ(tags)情報などの様々な情報が出力されます。リソースIDの粒度で請求書明細品目の内訳の確認、監査、請求書照合等の用途に有効活用できます。

コスト・レポートは、毎日6時間おきに自動的に生成され、Oracle所有のオブジェクト・ストレージ・バケットに格納されます。レポートには、OCIリソースID(ocid)ごと時間ごとに1行と、利用量(usage/billedQuantity)、利用コスト(cost/myCost)、単位価格(cost/unitPrice)、製品SKU番号(cost/productSku)、タグ(tags)情報等　が出力されます。コスト・レポートには、通常、6時間の使用状況データが含まれており、コスト・レポート自体は1年間保持されます。

使用状況レポートは、毎日4時間おきに自動的に生成され、Oracle所有のオブジェクト・ストレージ・バケットに格納されます。レポートには、OCIリソースID(ocid)ごと時間ごとに1行と、消費された利用量(usage/consumedQuantity)、請求された利用量(usage/billedQuantity)、タグ(tags)情報等　が出力されます。コスト・レポートには、通常、6時間の使用状況データが含まれており、コスト・レポート自体は1年間保持されます。

OCI管理コンソールからは「請求とコスト管理」-「コスト管理」-「コスト及び使用状況レポート」で下記の画面が現れます。

![スクリーンショット 2024-07-31 10.55.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849840/a87ee006-c430-dbd9-65be-7768db897538.png)

オブジェクト・ストレージ・バケット上のCSVファイルですが、名前は以下のようなネーミングになっています。

reports/cost-csv/000X0000000XXXXX-000Z.csv.gz コスト・レポート
reports/usage-csv/000Y0000000YYYYY.csv.gz 使用状況レポート
FOCUS/yyyy/mm/dd    FOCUS形式のレポート*
*FinOps Open Cost & Usage Specification (FOCUS)に準拠した業界標準のFOCUS CSVコスト・レポートも生成され、ダウンロードできます。
名前のリンクをクリックすると以下のようなコストレポートがダウンローされます。リソース毎に上述した使用量コスト(cost/myCost)、価格(cost/unitPrice)が見れます。
![スクリーンショット 2024-07-31 10.59.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849840/a95872c1-20c7-4deb-ce3f-19d67ac4f3ba.png)

レポート作成頻度やcsvファイル名/フィールド名等は現時点のものなので、ご利用いただくときは下記の参考情報にあるリンクOCI DOCSのマニュアル等を確認ください。

### 参考情報
[OCIドキュメント コストおよび使用状況レポート](https://docs.oracle.com/ja-jp/iaas/Content/Billing/Concepts/costusagereportsoverview.htm)
OCI Budgets

OCI(Oracle Cloud Infrastructure)にはお客様がコスト管理をするために無料で利用できる標準サービスが提供されており、順次紹介していきます。今回は第３回　OCI Bugedtsです。

第１回　OCI FinOps Hub
https://qiita.com/nsaka0315/items/e645bb0114e8e9a19dc4
第２回　OCI Cloud Advisor
https://qiita.com/nsaka0315/items/73906772854b675e11d5
第３回　OCI Bugedts(本稿)
第４回　OCI Cost&Usage Report
https://qiita.com/nsaka0315/items/d1faba63218596d8982b
第５回　OCI Cost Analysys
https://qiita.com/nsaka0315/items/61b65a1bc3ae7805a32f

## 予算
予算は、Oracle Cloud Infrastructureの費用支出に上限を設定するために使用します。予算にアラートを設定して、予算を超える可能性があるときに通知を受けることができます。
予算は、テナンシー、タグまたはコンパートメント(ルート・コンパートメントを含む)に設定されます。すべての予算アラートは、24時間ごとに定期的に評価されます。
また、OCIコンソールからすべての予算および利用状況を照会できます。

予算を使用するには、テナンシ(ルート・コンパートメント)のusage-budgetsを使用できるIAM権限が必要です。すべての予算は、ターゲットとしているコンパートメントに関係なくルート・コンパートメントに作成されます。　

予算やアラート・ルールを作成、編集および削除するためには下記のポリシーが必要です。

```
Allow group [グループ名] to manage usage-budgets in tenancy
```
では次に実際に予算を作成してみましょう。
OCI管理コンソールの左上のハンバーガーメニューより「請求とコスト管理」-「コスト管理」-「予算」を選択すると次の予算の一覧画面が現れます。

![スクリーンショット 2024-07-31 10.50.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849840/f1c4cc90-c991-1bb9-75dd-73ee42095272.png)

ここで「予算の作成」ボタンを押すと下記のような予算の作成画面が現れます。
予算の「名前」を入力して、「予算範囲」は予算設定する対象を指定しここではコンパートメントもしくはタグが選択できます。組織を利用しているアカウントであればテナンシーも選択肢として出てきます。「スケジュール」では毎月を選択して予算処理を開始する月の日付(デフォルト1日)を設定するか、もしくはカストム(臨時)を選択して予算処理開始・終了日付を自由に指定するか選べます。その後予算金額を入力します。
![スクリーンショット 2024-08-01 15.37.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849840/2796adeb-cca4-7f93-91e5-23436b28a8f9.png)

画面をスクロールすると下記のような予算のアラート・ルール(オプション)画面が現れます。ここで予算のアラートルールを作成できます。
「しきい値のメトリック」では(実績支出/予測支出)を選択でき、それぞれ予算期間内での実績の支出金額、予測金額を意味します。
「しきい値のタイプ」では　(予算比率/絶対金額)を指定できます、それぞれ上記で設定した予算金額に対する割合、絶対金額を表します。「しきい値」にはタイプに応じて割合もしくは金額を入力します。さらに電子メール受信者、電子メールメッセージを指定することも可能です。入力後「作成ボタン」を押すことで予算の作成は完了します。

![スクリーンショット 2024-08-01 15.42.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849840/02779204-6a46-495d-c0e0-26654f51f6a1.png)

１つの予算につき複数の予算アラート作成を作成することができます

予算が設定したしきい値に到達した時に受け取るアラートメールは下記の通りです。
![スクリーンショット 2024-08-01 15.24.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849840/f9b3dc18-ab15-8ae4-4de2-f5b4d1ae0a01.png)

予算名、タイプ、金額、支出金額、期間内の支出率および予測に関して表示されています。

## 参考情報
[OCIドキュメント　予算](https://docs.oracle.com/ja-jp/iaas/Content/Billing/Concepts/budgetsoverview.htm)
Redisの KEYS コマンドの利用は避けよう

# What is KEYS command

Redisには KEYS というコマンドでキーを確認することができます。
引数に pattern を渡すことで、文字列部分一致でキーの登録の確認ができるので使い勝手が良いかと思います。

You can check registered keys by calling KEYS to Redis.
When you pass pattern to KEYS, you can get by partial string matching.

https://redis.io/commands/keys/

# KEYS command makes performance trouble

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315979/cf75c36a-df7c-f2af-3a7b-365f665af3bf.png)


Redisのパフォーマンスに影響を与えます。
他のRequestが Timeout します。

KEYS command makes bad performance effect to Redis and at the time other requests may timeout.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315979/51f511bb-a198-1515-b6a1-1ea151f81213.png)



# What shoud we do

1. 代用のコマンド : alternative command
1. 使用する場合（非推奨）: call it to reader node.(not reccomended)

## alternative command

SCAN コマンドを使用する
Use SCAN command

https://redis.io/commands/scan/

3.x系だと以下
https://github.com/redis/redis-rb/blob/v3.3.5/lib/redis.rb#L2471-L2488

4.xからは type(data type を指定) が使える
From 4.x library we can specify data type
https://github.com/redis/redis-rb/blob/v4.8.1/lib/redis/commands/keys.rb#L6-L27


```ruby
irb(main):040:0> redis.scan(0, match: 'hoge*', count: 10)
=> ["4352", ["hoge_fuga:81141b0d9496d36e84eb8b6b2f319282", "hoge_fuga:5e49a2fe8396bd1f0bfa794aa6d3843d", "hoge_fuga:f4f0b518955b495584b6842de41bf8ac", "hoge_fuga:d0a0f8a87963df7f09f4d2dd42ff7046", "hoge_fuga:f43edc65a4e3c3057c4e901fee431315", "hoge_fuga:2eafa75ce47218635d94a198de4aa772", "hoge_fuga:59f716434011531905aae7535180ab94", "hoge_fuga:b956e1345782920854460232759e91f4", "hoge_fuga:a924c207c2de2182e380dc0162784285", "hoge_fuga:4c395e91dd05b5165c6109cd47d93e1f"]]
```

```bash

xxx.0001.apne1.cache.amazonaws.com:6379> scan 0 MATCH hoge_fuga:* TYPE string
1) "2304"
2)  1) "hoge_fuga:81141b0d9496d36e84eb8b6b2f319282"
    2) "hoge_fuga:5e49a2fe8396bd1f0bfa794aa6d3843d"
    3) "hoge_fuga:f4f0b518955b495584b6842de41bf8ac"
    4) "hoge_fuga:d0a0f8a87963df7f09f4d2dd42ff7046"
    5) "hoge_fuga:f43edc65a4e3c3057c4e901fee431315"
    6) "hoge_fuga:59f716434011531905aae7535180ab94"
    7) "hoge_fuga:b956e1345782920854460232759e91f4"
    8) "hoge_fuga:a924c207c2de2182e380dc0162784285"
    9) "hoge_fuga:4c395e91dd05b5165c6109cd47d93e1f"
   10) "hoge_fuga:7f3a16157431eba3fdbdb1dd0a680c6a"

```


## call it to reader node.(not reccomended)

どうしても使用したい場合は サービスで使用されている writer 側ではなくて、 reader 側で使用する
If you want to use KEYS command, you should call it to reader node.

```ruby
irb(main):032:0> redis=Redis.new({host: 'xxx.ng.0001.apne1.cache.amazonaws.com', port: 1234, db: 0, driver: :ruby, timeout: 
1})
=> #<Redis client v3.3.5 for redis://xxx.i3gcdw.ng.0001.apne1.cache.amazonaws.com:1234/0>
```

```bash
$ redis-cli -h xxx.ng.0001.apne1.cache.amazonaws.com
xxx.ng.0001.apne1.cache.amazonaws.com:1234>
```


ちなみに、ElastiCache Redisは設定で禁止コマンドを登録することができるので、
KEYSコマンドを禁止にしてしまうのは良い戦略かと思います。
WinUI3で、Microsoft Store用に、MSIXパッケージを作成する

2024-8-20時点です。

WinUI3のテンプレートで、プロジェクトを作成します。
このテンプレートを利用すると、MSIXパッケージを作成しやすいようです。

![20240820 221807 MicrosoftVisualStudio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132059/6309a721-4a07-f345-1744-2d5ef6935be0.png)

プロジェクトを、ビルドやリビルドします。
すると、プロジェクトのコンテキストメニューに、
**パッケージ化して公開する**という項目が表示されます。
ビルドしないと、この項目が表示されません（→　これが分からず、はまった点です）

![20240820 222040 Anonymous.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132059/1e226aff-dedd-d025-41e1-a2af4aac81f1.png)

例えば、次のようなフォルダに、msixファイルが出力されます。

`\bin\x64\Release\net8.0-windows10.0.19041.0\win-x64\AppPackages\HOGEHOGE_1.0.0.0_x64_Test`

ファイル　`HOGEHOGE_1.0.0.0_x64.msix`


このファイルを、Microsoft パートナー センターで、登録すればよいようです。

### 環境
- Microsoft Visual Studio Community 2022 (64 ビット) Version 17.11.0

### 参考
- [MSIX とは](https://learn.microsoft.com/ja-jp/windows/msix/overview)
- [MSIX アプリのアプリ パッケージ要件](https://learn.microsoft.com/ja-jp/windows/apps/publish/publish-your-app/msix/app-package-requirements)
【ChatGPT＋Code Interpreter】で音声の重ね合わせをやってみました。


　どうも、カーブミラーです。

　今回は、音声の重ね合わせをやってみました。

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
ありません。　あしからず。
:::

　ニュースはないので、
　　さっそく本題です。

　音声の重ね合わせが
　　できないかと
　　　やってみました。

　BGMに音声を
　　かぶせたかったんです。

　Qiitaには
　　音声ファイルの
　　　アップロードが
　　　　できませんので
　　　　　出来上がりは出せません。

　とりあえず、
　　Promptをどうぞ。

```Text:音声の重ね合わせPrompt
CodeInterpreterで、
ふたつの音声ファイルを合成してください。
コード不要。
実行してください。
```

　ふたつの音声ファイルを
　　アップロードしてから
　　　このPromptを送信しました。

　実はこれでは
　　BGM側が音声側に
　　　塗りつぶされてしまいました。

　ようするに
　　失敗です。
***
　それで
　　いろいろとやりました。

　その結果をもとに
　　ChatGPTさんに
　　　指示Promptを
　　　　作成してもらいました。
```Text:音声の重ね合わせ成功Prompt
### 指示Prompt

1. **Pydubライブラリを使用して、2つの音声ファイルを重ねる。**
   - 前者のファイル（BGMとなる音声ファイル）を `bgm_audio` として読み込む。
   - 後者のファイル（音声読み上げ）を `speech_audio` として読み込む。

2. **BGMの音量を調整する。**
   - BGMの音量を元の音量から**+2dB**に設定する。

3. **音声読み上げの音量を調整する。**
   - 音声読み上げの音量を元の音量から**+10dB**に設定する。

4. **音声を重ねる。**
   - `speech_audio` を `bgm_audio` に重ねて合成する。

5. **合成した音声をMP3形式でエクスポートする。**
   - 出力ファイル名は自動生成させる。
```

　これで、
　　BGMに読み上げ音声が
　　　重なる音声ファイルが
　　　　生成されます。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
Paiza×Qiitaキャンペーン Javaで解説してみた【C Fizz Buzz 編】

# 問題へのリンク

https://paiza.jp/works/mondai/c_rank_skillcheck_sample/fizz-buzz

# 解答コード

<details><summary>詳細</summary>

~~~

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);

		final int N = scanner.nextInt();

		StringBuilder sb = new StringBuilder();

		for (int i = 1; i <= N; i++) {
			if (i % 15 == 0) {
				sb.append("Fizz Buzz");
			} else if (i % 3 == 0) {
				sb.append("Fizz");
			} else if (i % 5 == 0) {
				sb.append("Buzz");
			} else {
				sb.append(i);
			}

			sb.append("\n");
		}

		System.out.println(sb);
		scanner.close();
	}
}

~~~

</details>

# 解説

<details><summary>詳細</summary>

XがYの倍数かどうかを判定したい場合、Yで割った時の余りが0かどうかを見ると良いです。
ですので

3*5=15で割り切れる
3で割り切れる
5で割り切れる
それ以外

の4分岐すると楽です。

取り扱う数字は1~Nですので、iの初期値は1、継続条件はi<=Nにしないといけません。

</details>
Reactで発生する「Warning: Each child in a list should have a unique “key” prop.」

## アジェンダ
Reactで発生する「Warning: Each child in a list should have a unique “key” prop.」という警告の解消方法について簡単にまとめます。
![hoge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961835/6ad606de-995d-adaf-ac00-72490c618055.png)
この警告はエラーメッセージ通りの内容ですが、備忘録として記録します。

## エラーの原因と解決法
このエラーメッセージを日本語にすると次のようになります。

> 警告: リスト内の各子要素はユニークな "key" プロパティを持つ必要があります。

この警告が表示される主な原因として、以下の2つが考えられます。

### 1. `key` プロパティが定義されていない
**原因:**
リスト内の要素にkeyプロパティが定義されていない場合、この警告が表示されます。

**解決法:**
要素にkeyプロパティを定義することです。
`map`メソッドを使用して要素を生成している場合は、第2引数の`index`を使用して`key`プロパティを定義することで解決できます。

### 2. `key` プロパティがユニークでない
**原因:**
リスト内の要素に設定されたkeyプロパティがユニークでない(keyが重複しているということ)場合、この警告が表示されます。

**解決法:**
keyが重複しないようkeyプロパティを定義する。

## 参考文献
- [React.jsでWarning: Each child in a list should have a unique "key" prop.が発生した時の原因と対処法 #JavaScript - Qiita](https://qiita.com/ikeike_ryuryu/items/edec3acfce7868e4b0d0)
- [Reactアプリでの「Warning: Each child in a list should have a unique “key” prop.」の回避はコンポーネントの呼び出され側ではなく呼び出し側で行う | DevelopersIO](https://dev.classmethod.jp/articles/avoiding-warningeach-child-in-a-list-should-have-a-unique-key-prop-in-react-apps-is-called-and-not-on-the-side-do-it-on-the-caller/)
【React✖️FramerMotion】画面を遷移させたい！


# 研修中の開発備忘録です！

## はじめに！
```tsx
import { motion, AnimatePresence } from "framer-motion";
import { useLocation } from "react-router-dom";

```

+ 事前準備は大事
## 今回のメイン
```tsx
const RouteWrapper: React.FC = () => {
    const location = useLocation();

    return (
      <AnimatePresence>
        <motion.div
          key={location.pathname}
          initial={{ opacity: 0.8, scaleX: 1 }}
          animate={{ opacity: 1.0, scaleX: 0 }} // X軸方向に縮小
          exit={{ opacity: 0.5, scaleX: 0 }} // 元のサイズに戻す
          transition={{ duration: 1 }}
          style={{
            position: "absolute",
            top: 0,
            left: 0,
            width: "100%",
            height: "100vh",
            backgroundColor: "#E3027E",
            zIndex: 10,
            transformOrigin: "right", // 縮小時に右端を基準にする
          }}
        />
        <motion.div
          key={location.pathname}
          initial={{ opacity: 1 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 1 }}
          transition={{ duration: 1.5 }}
          style={{ position: "relative", width: "100%", height: "100%" }}
        >
          //適用するコンポーネント
        </motion.div>
      </AnimatePresence>
    );
  };
```
## 細かい説明
#### 全体
<dl>
<dt>・　RouteWrapperコンポーネント</dt>
<dd>・ページ遷移のアニメーションを管理するためのコンポーネント</dd>
<dt>・　useLocationフック</dt>
<dd>・現在のルートの場所を取得し、ページの遷移を検知してアニメーションを制御する</dd>
<dt>・　AnimatePresenceコンポーネント</dt>
<dd>・Framer Motionのコンポーネントらしい...</dd>

#### motion.div（背景）
<dl>
<dt>・keyプロパティ</dt>
<dd>・location.pathnameをキーとして指定することでページ遷移時に背景のアニメーションが適切にリセットされる</dd>
<dt>・initialプロパティ</dt>
<dd>・透明度は0.8、X軸方向のスケールは1</dd>
<dt>・animateプロパティ</dt>
<dd>・透明度を 1.0 に上げ、X軸方向に縮小させる</dd>
<dt>・exitプロパティ</dt>
<dd>・透明度を0.5 にし、X軸方向に縮小させる（scaleX: 0）</dd>
<dt>・transitionプロパティ</dt>
<dd>・アニメーションの期間（今回は１秒）</dd>

#### motion.div（コンテンツ）　
<dl>
<dt>・styleプロパティ</dt>
<dd>・コンテンツのスタイル設定（今回はrelative）</dd>

## 参考
[FramerMotion公式](https://www.framer.com/motion/introduction/ "Framer Motion")
Crystalで出力した実行ファイルが常にlibpcre2にリンクされてしまう問題を修正した話

## はじめに

Crystal言語はRubyに似た静的型付けのプログラミング言語です。Rubyほどの柔軟性はありませんが、ほとんどRubyのような見た目のコードが、CやRustに匹敵する速度で動作するのが痛快です。

## Crystalが常にlibpcre2をリンクする問題

Crystalは大企業のバックアップがない、小さなコミュニティによって運営されている言語であり、いくつかの外部ライブラリに依存しています。例えば、ガベージコレクションはlibgc-devに依存しており、ファイル出力などはlibevent-devに依存しています。

Crystalは正規表現に[libpcre2](https://github.com/PCRE2Project/pcre2)を利用しています。

しかし、正規表現を使用しないコードをコンパイルしても、libpcre2にリンクされてしまうという問題がありました。

```crystal:hw.cr
puts "hello world"
```

```
ldd hw
# 正規表現を使っていないのにlibpcre2にリンクされてしまう
```

## 調査してみた

本来は、gdbやlldbをもっと活用すべきだったと思います。

でも今回はLLVM-IRを出力して調査しました。実際にLLVM-IRをコンパイルすることで、ビルドフラグにライブラリが必要かどうかを確認できます。

```cr:hw1.cr
puts "hello world"
```

このコードをコンパイルして、含まれている関数を確認します。

```
crystal build --release hw1.cr
nm hw1
```

::: note
特に指定がない限り、Crystalは以下のライブラリをロードします。
https://github.com/crystal-lang/crystal/blob/master/src/prelude.cr
:::

```
nm hw1 | grep pcre2
```

grepで検索すると、

```
                 U pcre2_config_8
```

この関数が呼び出されていることがわかります。次に、中間表現LLVM-IRを出力します。

```
crystal build --emit llvm-ir hw1.cr
```

`hw1.ll`は次のリンクフラグでコンパイルできます。このコンパイルには`-lpcre2-8`が必要です。

```
clang hw1.ll -lm -lz -levent -lgc -lpcre2-8
```

`hw1.ll`をテキストエディタで開き、`pcre2`を検索すると次の宣言が見つかります。

```
declare i32 @pcre2_config_8(i32, ptr) local_unnamed_addr
```

ここで使用されています。

```  
  %41 = call i32 @pcre2_config_8(i32 11, ptr %40), !dbg !17427
```

次の行を以下のように変更してみます。

```
  %41 = add i32 0, 17
```

これで、pcre2なしでコンパイルできるようになります。

```
clang hw1.ll -lm -lz -levent -lgc
```

pcre2へのリンクがないことを確認します。

```
ldd a.out
```

実行するとエラーが発生します。

```
Unhandled exception: Invalid libpcre2 version (RuntimeError)
  from /usr/local/share/crystal/src/regex/pcre2.cr:18:33 in '~Regex::PCRE2::version_number:init'
```

問題は標準ライブラリの`Regex::PCRE2`のこの部分にあります。

```cr
module Regex::PCRE2
  @re : LibPCRE2::Code*
  @jit : Bool

  def self.version : String
    String.new(24) do |pointer|
      size = LibPCRE2.config(LibPCRE2::CONFIG_VERSION, pointer) ## %41 HERE!!
      {size - 1, size - 1}
    end
  end

  class_getter version_number : {Int32, Int32} = begin
    version = self.version
    dot = version.index('.') || raise RuntimeError.new("Invalid libpcre2 version") ## THE ERROR!!
    space = version.index(' ', dot) || raise RuntimeError.new("Invalid libpcre2 version")
    # PCRE2 versions can contain -RC{N} which would make `.to_i` fail unless strict is set to false
    {version.byte_slice(0, dot).to_i, version.byte_slice(dot + 1, space - dot - 1).to_i(strict: false)}
  end
```

この行の呼び出しが`%41`と一致します。

```cr
LibPCRE2.config(LibPCRE2::CONFIG_VERSION, pointer)
```

この行が実際に行っているのは、libpcre2のバージョンの取得です。そこで、バージョンを直接指定すると、

```
    version = "10.42 2022-12-11" # self.version
```

`pcre2`がリンクされなくなります。

```
crystal build hw1.cr
ldd hw1
```

さらに調査を進め、`class_getter`が`begin`で始まっているのが問題であることがわかったので、修正するプルリクエストを送りました。このプルリクエストはマージされ、1.14から適用される予定です。今後は、Crystalで作成した任意のプログラムがlibpcre2にリンクされることはなくなるはずです。

https://github.com/crystal-lang/crystal/pull/14891

## まとめ

Crystalは小さなコミュニティが支える言語であり、現在も日々改良が続けられています。ソースコードもCrystalで書かれているため、RubyやPythonのような文法に慣れている人は、それなりに簡単にバグを特定できるでしょう。今回Crystalに意味のあるプルリクエストを送ったのは2回目だったので、とても嬉しくなり、この記録記事を書きました。

Crystal言語をどうぞよろしくお願いします。

この記事は以上です。
大規模プロジェクトのためのパフォーマンス最適化：JetBrainsエディタで不要なインデックスを除外する方法

## 背景
プロジェクトが大規模になるとファイル数が増加し、JetBrains の各エディタ（RubyMine、WebStorm、PyCharm など）でコードを保存するたびにインデックスの再構築が必要になり、作業効率が著しく低下する。

こんな感じで、ずっと待たされ、辛い。。

![スクリーンショット 2024-08-21 11.00.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634885/e51b1439-a039-db1e-593b-f8c9fd259540.png)



## なぜインデックスを貼りたいか？
インデックスを貼ると、関数や変数にジャンプやファイル検索などが迅速に行える。
JetBrains の関数や変数へのジャンプがとても優秀だから、JetBrains のエディタをここ数年愛用している。
だから、インデックスを貼る機能は、何としても利用したい！

## 解決策
インデックスを貼るディレクトリを制限する
= インデックスを貼る必要がないディレクトリを除外する

## やり方
インデックスを貼りたくないディレクトリで右クリックし、
コンテキストメニューから `Mark Directorty as > Excluded` を選択
![スクリーンショット 2024-08-21 11.08.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634885/4164b53e-5cbf-72e4-47bd-fef4d2f01acf.png)

ディレクトリの色が変更されたら、インデックスの対象外となっており成功

こんなイメージ↓
![スクリーンショット 2024-08-21 11.01.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634885/5e24c954-0eed-af89-c8af-90316b7f1535.png)

## 結果
コードの保存時に発生するインデックスの再構築が大幅に減少し、エディタの反応速度が向上した。
特に大規模なプロジェクトでの作業効率が改善され、ストレスなくコーディングが可能になる。

## まとめ
JetBrains の各エディタ（RubyMine、WebStorm、PyCharm など）は非常に強力だが、大規模なプロジェクトではパフォーマンスの低下が問題となることがある。不要なディレクトリをインデックスから除外することで、これらの問題を効果的に解決し、快適な開発環境を維持することができる。

JetBrains愛用家として、JetBrains のエディタがさらに多くの開発者に利用されることを願っている。
AWS資格取得特典をサクッと紹介

# はじめに

AWS資格取得に関する特典をまとめました。
※ 資格合格に向けた知識・情報は記載していません。


:::note info
[弊社オープントーン](https://qiita.com/organizations/opentone)は社内のAWS業務を支援する「AWSチーム」が、
各AWSアカウントの費用管理やAWSへの技術的な問合せ対応などを行っています。
今回は、社内外向けの活動として記事を投稿しました。
:::

# 主な特典

|特典|内容|
|:--|:---|
|クレジット|AWS利用料金に充てられる|
|バウチャー|AWS受験料を割引できる|
|サービス|イベント・グッズ販売サイトの利用|



## クレジット

- クレジットを登録するとサービスの請求書に自動的に適用されます。
金額は100~500＄です。

## バウチャー

- AWSの受験料が割引きされます。
  バウチャーの割引率は25%～50%、または再受験の無料などです。

- X（旧Twitter）でバウチャーを獲得できるキャンペーンが告知されることもあります。
  ※ 受験前の事前登録により、受験料が割安になるキャンペーンもあるのでご注意ください。

https://x.com/awscloud_jp

## サービス

資格取得者向けのイベントやグッズ販売もあります。

- AWS認定グッズのオフィシャルストア：[AWS認定グッズ](https://www.amazon.co.jp/stores/page/250E2DBB-512B-4B52-8A89-B63CCB09AEEC)

  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743373/3f0ca727-5d83-4820-8365-90fca9747525.png)

- AWSサミット：AWS 認定者ラウンジ [EXPO - AWS Summit Japan](https://aws.amazon.com/jp/summits/japan-2024/expo/)
  保有している認定のキャラクターステッカーがもらえます。

  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743373/8e6759bf-d71b-0434-3a18-54ae3a872b75.png)

## その他特典について

### クレジットの適用

- AWSクレジットの適用方法は以下のリンクをご参照ください。 
  [AWS クレジットの適用](https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/useconsolidatedbilling-credits.html)

- ※ クラスメソッドでAWSの請求代行サービスを利用している場合、クーポンの適用方法が異なることがあります。
  [AWSのクレジットやクーポンはメンバーズ利用中のアカウントでも利用できますか？](https://helpdesk.classmethod.net/hc/ja/articles/360022732994)


### クレジット・クーポンはイベント・キャンペーンでも獲得できる

資格取得の他に「AWSイベントに参加」「アンケートの回答」などでも手に入ります。
- AWSニュース関連の紹介サイト：
  - [X公式アカウント](https://x.com/awscloud_jp)
  - [AWS の最新情報](https://aws.amazon.com/jp/new/?whats-new-content-all.sort-by=item.additionalFields.postDateTime&whats-new-content-all.sort-order=desc&awsf.whats-new-categories=*all)
  - [Tag: 週刊AWS](https://aws.amazon.com/jp/blogs/news/tag/%E9%80%B1%E5%88%8Aaws/)
  - [クラスメソッド：AWS の記事一覧](https://dev.classmethod.jp/tags/aws/)

### 参考リンク

- [AWS 認定を受ける利点](https://aws.amazon.com/jp/certification/benefits/)
- [AWSアカウントにAWSクレジットを適用してみた](https://dev.classmethod.jp/articles/how-to-apply-aws-credit-to-your-aws-account/)
 - [AWS Summit Japan 2024 に行こう！事前登録のやり方とおすすめの楽しみ方](https://dev.classmethod.jp/articles/lets-go-to-aws-summit-japan-2024/)
 - [AWS 認定者ラウンジに行ってきた #AWSSummit](https://dev.classmethod.jp/articles/i-went-to-the-aws-certified-persons-lounge/)

## まとめ
資格特典のクレジットやバウチャーによって費用を抑えられるのは大きなメリットです。
各種クレジットの適用方法やイベント参加などを通じて、資格取得のサポートも提供しています。  
ぜひ参考にしていただければと思います。
No route matches [POST] "/posts/new"エラーについて

復習のため、投稿機能を作成しようとしたところ、上記のエラーが出たので、解決方法をまとめます。

・ログイン後のユーザーが、投稿を行えるようにしたい
・sorceryを導入し、ユーザー登録機能は実装済み
・userとpostのデータの関係は、１対多である。

コードの内容
```routes.rb
Rails.application.routes.draw do
  root 'top#index'
  get 'login', to: 'user_sessions#new'
  post 'login', to: 'user_sessions#create'
  delete 'logout', to: 'user_sessions#destroy'
  resources :posts
  resources :users
end
```
```models/post.rb
class Post < ApplicationRecord
  belongs_to :user, dependent: :destroy
  validates :user_id, presence: true
  validates :title, presence: true
  validates :content, presence: true
end
```
```models/user.rb
class User < ApplicationRecord
  has_many :posts, dependent: :destroy
  authenticates_with_sorcery!

  validates :password, length: { minimum: 3 }, if: -> { new_record? || changes[:crypted_password] }
  validates :password, confirmation: true, if: -> { new_record? || changes[:crypted_password] }
  validates :password_confirmation, presence: true, if: -> { new_record? || changes[:crypted_password] }
  validates :email, presence: true, uniqueness: true
end
```
```views/posts/new.html.erb
<%= form_with model: @post,local: true do |f| %>

  <p><%= f.label :title %><br>
  <%= f.text_field :title %></p>
  
  <p><%= f.label :content %><br>
  <%= f.text_area :content %></p>
  
  <%= f.submit "投稿する", class: "btn btn-primary" %> 
<% end %>
```
## 解決方法
以下のようにcreateメソッドを修正したところ解決
```app/controllers/posts_controller.rb
class PostsController < ApplicationController

  def new
    @post = Post.new
  end

  def create
    @post = current_user.posts.build(post_params)
    if @post.save
      flash[:success] = "記事が作成できました。"
      redirect_to @post
    else
      flash[:danger] = "記事の作成が失敗しました。もう一度試してください。"
      render action: 'new'
    end
  end
  
  private
    def post_params
      params.require(:post).permit(:title, :content)
    end
end
```
@post = current_user.posts.build(post_params)の部分を、当初は@post = Post.new(post_params)としていた。
現在ログイン中のユーザーと投稿する本を紐づけるためには、sorceryのcurrent_userメソッドが必要(現在ログイン中のuserを返すメソッド)
また、モデルの関係性は、1対多の関係のため、postは複数形にする必要がある。

※補足
newメソッドとbuildメソッドは、インスタンスを生成するメソッドという点では共通しているので、buildをnewに変えても登録することが可能。しかし、モデルの関連付けの際にはbuildを使用する。
モデルを関連づけた際にはbuildメソッドを使用することが暗黙の了解。

参考

https://zenn.dev/redheadchloe/articles/f3cf7ef743904c

https://techtechmedia.com/build-method-rails/
NullPointerExceptionについて考えてみる。

# Nullとは
Javaにおけるnullポインターエクセプションとは、プリミティブ型にnullが設定されている状態でnull処理をされていない呼び出しが行われたときに発生する例外のことである。
例えば、
```
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        String i=null;
        System.out.println(i.length());
    }
}
```

上記のソースコードをコンパイルするとコンパイルは正常完了するが、実行の際に、実行時エラーとしてnullポインターエクセプションを出してしまう。

# 実務におけるnullポインターエクセプション例外の処理

実務では基本的にJavaとデータベースなどを組み合わせて使う場合が多い。データベースでnullが設定されている場合にはJava側に関してもnullが設定されてしまうことが多い。そのため、nullが設定されている項目に関してはnullポインターエクセプションを出さないために、nullの例外処理を書くのが通例ではある。
ただ、nullになりうるすべての項目に対してnull処理を書く必要があるかどうかといわれれば別であると思う。特にデータベース上で必須項目として設定されている項目に対し、さらにJava側でわざわざnull例外のための回避処理などをする必要はないと思われる。後続処理においても必須項目に関してnull例外の処理が必要となってしまうため。