OmniAICreator/Qiita-1.07M huggingface dataset:
【Java 入門】BOM付き/無しのUTF-8のテキストファイルのイメージ・扱い方


# [経緯] 執筆までのいきさつ
ボス：うちで開発中のシステムの対向システムがどうやらBOM付きのCSVを渡すらしいから、こっちもBOM付きのままのCSVを受け取って今まで通り処理出来るようにしてくれやー
筆者：仰せのままに
筆者（心の中）：ボム(BOM)って言った？ドム(DOM)ならフロント周りとかでちょっとは知ってるけど、BOMってなんだ？？
筆者：うーん。うちのシステムはJavaだし、ひとまず「Java ボム付き CSV」って検索するか
筆者：カタカタカタカタ…。一応、なんとかなったー
ボス：今年もクリスマスの時期が来るらしいから、この1年で学んだことの一つや二つをQiitaに投稿してくれやー
筆者：仰せのままに
筆者（心の中）：せっかくだし、さっきやったBOMのことを備忘録としてまとめておこう！

# [概要] BOMの正体を探る
### ①BOMとは
正式名称は、**バイト・オーダー・マーク（byte order mark）**
Unicode（）で記載されたテキストファイルの先頭に書かれている、そのファイルの形式を識別する特別な文字列（バイト）のようなイメージ
 **UTF-16**の場合) 上記の文字列によって、該当のテキストファイルを解釈する際の順番が異なる
 **UTF-8** の場合) 上記の文字列によって、該当のテキストファイルがUTF-8が使われていることがわかる
→今回は**UTF-8**の場合に関して取り上げます！

### ②BOM付き/無しによる差異 ※一部抜粋
#### ◆BOM無し
1) CSVやTSVファイルをExcelで開いた際に**文字化けする**ため、利用者は内容を認識出来ない
2) ファイル読み込み時の通常通りの処理で問題無し

#### ◆BOM付き
1) CSVやTSVファイルをExcelで開いた際に**文字化けしない**ため、利用者は内容を認識しやすい
2) システムがBOM付きの考慮をしていないと、テキストファイル読み込み時にバグが起きる？
→上記の 1 で記載したように、Excel側がBOMを読み込んでUTF-8でExcelを表示している。そのため、UTF-8のBOM付きはテキストファイル先頭に識別のための特別な文字列が付与されているイメージのため、テキストファイルを読み込む処理を実施時にBOM付きへの考慮がされていないとBOM文字列 + テキストファイル先頭の内容、と本来の読み込む内容に加えてBOMが読み取られるため、BOMを削除してから読み込む等の考慮が無いとシステムが想定外の動きを起こしてしまう。

#### ◆テキストエディタやExcelで開いた際のイメージ
サクラエディタで開いた際にはUTF-8 BOM付と記載される。
設定 > 文字コードセット設定 > 文字コードセットからUTF-8 を選択、BOMにチェック
![sakura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944837/d5553be8-7fbc-004f-6e66-2df4f0139f97.png)
BOM付きのテキストファイルをExcelで開くと、文字化けせず読みやすい
![excel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944837/a3fd7cac-018d-12ba-f16c-f82ae4cb7f3f.png)


# [処理例] Javaでの書き方
主に2つ、①テキストファイルを読み取った際にテキストファイル先頭に記載されているBOMを削除して元々のテキストファイルの内容の読み取りにつなげる処理、②諸々の内容を記載し最後にテキストファイルの先頭にBOMを付与する際の処理を参考記事を元に紹介します。

### ①BOM付きテキストの読み取り
・処理概要：テキストファイルのN行目を引数で貰い、先頭文字からBOMを削除して返却
```Java
public class ReadBOM {

 /**
  * BOM付きのテキストをBOM無しに変換 ※参考記事から抜粋
  */
 public static void read(String row) {
     String bom = row.substring(0, 1);
     // 先頭文字をバイトを文字に変換する(Apache Commons CodecのHexクラスを利用)
     String bomByte = new String(Hex.encodeHex(bom.getBytes()));
     if ("efbbbf".equals(bomByte)) {
         //BOMを排除
         row = row.substring(1);
     }
     System.out.println(row);
 }
}
```

### ②テキストファイルへのBOMの書き込み
・処理概要：内容が書き込まれたテキストファイルの先頭3byteにBOM、「0xef」、「0xbb」、「0xbf」を埋め込む

```Java
public class AddBOM {

    /**
     * BOM付きのCSVファイルを作成（文字コードはUTF-8）※参考記事から抜粋
     *
     * @param 
     * @return 
     */
    public static void main(String[] args) {

        try(FileOutputStream fos = new FileOutputStream("アウトプットファイルのパス");
            OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
            PrintWriter writer = new PrintWriter(osw)){

            // テキストファイル先頭3byteにBOM（「0xef」、「0xbb」、「0xbf」）記載
            fos.write(0xef);
            fos.write(0xbb);
            fos.write(0xbf);

        } catch (IOException e) {
            System.out.println("ファイルの生成に失敗。");
        }
    }
}
```

# 参考記事
・BOM (Byte Order Mark) - XML用語事典 - ITmedia
https://atmarkit.itmedia.co.jp/aig/01xml/bom.html
https://alaki.co.jp/blog/?p=1236
・BOM付きのCSVインポート
https://qiita.com/tomoya-misuda/items/49c251b717b0c697634a
cssのimage-set()を使用して最適な画像を表示させよう！

# はじめに
皆さまは日頃からブラウザやデバイスの対応状況に応じて最適な画像の設定をしていますか？

AVIF、Webp、レティナ対応...と様々な設定をしていると思います。
中でも`<picture>`にはお世話になっている人も多いと思います。

ですがこれには問題があります。


# `<picture>`の問題点
例えば、`<picture>`でWebP形式に対応しているブラウザにはWebP画像を、それ以外にはPNGやJPEG画像を表示させるには下記の設定をします。

```css
<picture>
  <source srcset="image.webp" type="image/webp">
  <img src="image.png" alt="画像">
</picture>
```

当然ながらこれではcssの背景画像や装飾ではこの方法は使用することが出来ません。

cssで実現するにはJavaScriptを使用して上手く切り替えるか、妥協をしてpngをそのまま使用することになってしまいます。


# image-set()の登場
そこでCSSのimage-set()を使用することで、この問題を解決できます。以下はその基本的な使い方の例です。

https://developer.mozilla.org/ja/docs/Web/CSS/image/image-set

```css
.element {
  background-image: image-set(
    url("image.webp") type("image/webp"),
    url("image.png") type("image/png")
  );
}
```

このコードは、ブラウザがWebP形式に対応している場合はimage.webpを、それ以外の場合はimage.pngを背景画像として表示します。

解説
- url(): 画像のURLを指定します
- type(): 各画像のフォーマットを明示します
- ブラウザは自動で対応可能な形式を確認し、最適な画像を選択します

画像のtype指定は下記参照ください。
https://developer.mozilla.org/ja/docs/Web/Media/Formats/Image_types

さらに、解像度・画質を考慮した切り替えも可能です。

```css
.element {
  background-image: image-set(
    url("image@1x.png") 1x,
    url("image@2x.png") 2x
  );
}
```

この例では、デバイスの画面解像度に応じて1xまたは2xの画像が選ばれます。
これにより、AppleデバイスのRetinaディスプレイなどの高解像度デバイスにも最適な画像を提供できます！

## 注意点
`image-set()`にはフォールバックが存在しない為、設定した画像全てが読み込めなかった場合に備えて`url()`での記載も必要になる場合があります。

```css
.element  {
  background-image: url("large-balloons.jpg");
  background-image: image-set(
    url("image.webp") type("image/webp"),
    url("image.png") type("image/png")
  );
}
```

## ブラウザ対応状況

https://caniuse.com/mdn-css_properties_content_image-set

以前は`-webkit`をつける必要がありましたがiOS17で不要になった事でメジャーなブラウザではそのまま利用することができます。

# まとめ
image-set()を使えば、CSSでより柔軟に画像を管理できるようになります。
背景画像や装飾に最適な形式や形式を提供し、パフォーマンスを向上させつつユーザー体験を高めていきましょう！
PyGameを簡易版Manimとして使う

# 何故そんな事をするのか?

Manimの使い方を既に心得ている人はこの記事は読まなくていいかもしれません。これは私のようにPyGameの使い方は心得ているけどManimを学ぶ気力が無いのでPyGameの知識をそのまま活かしてアニメーションを作りたいという人向けの提案となります。

また何も動画作成に特化した事をするわけではないので、これから行うことはリアルタイムで動くPyGameプログラムでもそのまま使える知識となります。なので動画とPyGameプログラムの作り方を同時に学べるという利もあります。

<!--
普通にPyGameプログラムを実行してOBSのようなソフトウェアで画面を録画すればいいのでは？という声もあるかもしれません。しかしこのやり方だとプログラム実行中のPCにかかる負荷にもろに依存してしまって安定したフレームレートを望めなくなってしまいます。また動画の再生時のフレームレートよりも速い速度で動画を作る事も難しそうです。

これから行うやり方では動画生成時の経過時間は品質には影響を与えません。
-->

# 描かれたフレームをffmpegに流し込むだけ？

動画生成自体は極論それだけやればできますがそれだけならわざわざ記事に取り上げる程の物ではないでしょう。取り上げた理由は私が作っているasyncライブラリを用いる事でかなり良い感じにコードを書けると思ったからです。

https://github.com/asyncgui/asyncpygame

async/await構文の利点については多くの文献で語られているのでここでは触れませんが、とりあえずアニメーションに役立つ機能が豊富なので紹介します。

# 黄色い正方形が画面の端を周るアニメーション

```python3
from typing import Unpack
from functools import partial

import pygame
from pygame.colordict import THECOLORS
import asyncpygame as apg


async def main(**kwargs: Unpack[apg.CommonParams]):
    pygame.init()

    screen = pygame.display.set_mode((240, 240))
    screen_rect = screen.get_rect()

    dest = pygame.Rect(0, 0, 40, 40)

    r = kwargs["executor"].register
    r(partial(screen.fill, THECOLORS["black"]), priority=0)
    r(partial(pygame.draw.rect, screen, THECOLORS["yellow"], dest), priority=0x100)
    r(pygame.display.flip, priority=0xFFFFFF00)

    anim_attrs = kwargs["clock"].anim_attrs
    while True:
        await anim_attrs(dest, right=screen_rect.right, duration=500)
        await anim_attrs(dest, bottom=screen_rect.bottom, duration=500)
        await anim_attrs(dest, left=screen_rect.left, duration=500)
        await anim_attrs(dest, top=screen_rect.top, duration=500)


if __name__ == "__main__":
    apg.run(main)
```

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144673/29dc23bc-fb61-dc96-1fae-0a4811d39be0.gif)

# 解説

`kwargs["executor"].register` で登録した関数達は毎フレーム`priority`の値が小さい順に呼ばれます。なので上記の例ではフレーム毎に

1. `screen.fill`
1. `pygame.draw.rect`
1. `pygame.display.flip`

の順に呼ばれます。`register`はコンテキストマネージャを返し、その `__exit__()`が呼ばれた時に登録を解除するのでwithブロックを用いて登録の有効範囲を視覚的に分かりやすく書き表せます。

```python
# 小規模ではないアプリケーションではこれが主力となる書き方です
r = kwargs["executor"].register
with (
    r(func1, priority=...),
    r(func2, priority=...),
):
    ...
```

`kwargs["clock"].anim_attrs` は任意のオブジェクトの属性を時間をかけて徐々に変化させます。上の例ではwhileループ内で `Rect`のインスタンスである`dest`の

1. 右端(right)を500msかけて`screen_rect.right`に変化させる
1. 下端(bottom)を500msかけて`screen_rect.bottom`に変化させる
1. 左端(left)を500msかけて`screen_rect.left`に変化させる
1. 上橋(top)を500msかけて`screen_rect.top`に変化させる

としています。

# 動画生成

上の例では動画生成はしていません。そうしたい時は`apg.run()`に代えて`apg.run_and_record()`を用いるだけです。

```python
if __name__ == "__main__":
    apg.run_and_record(main, outfile_options=r"-codec:v gif -lossless 1 -loop 0".split(), outfile="./output.gif")
```

# おわりに

`asyncpygame`の機能はManimほど豊富ではありませんが、PyGame上で使えるものなら何でも使えるため潜在能力は高いと思っています(例えば`Pymunk`のような物理エンジン)。
【PICT】F5で実行し、結果を自動保存するデバッグ構成【VSCode】

# はじめに
複雑性の高い制約を指定したいときほど、
GUIツールよりもVSCode等で制約文を直接書いてしまったほうが楽だ。

ただ、これでも以下の4ステップを実施する必要があり、まあまあ面倒。
1. PICTファイルの配置されたディレクトリまでcdコマンドで移動
1. pictコマンド実行
1. コンソール上の実行結果をコピー
1. バックアップ的に、適当なテキストファイルに保存

これらをF5(デバッグ実行)で自動的に行なってもらうためのデバッグ構成を作った。

# PICT向けデバッグ構成
:::note info
前提条件
- VSCodeがインストールされている
- PICTがインストールされている。
- PICTのPATHが通っている
- 今回はWindoows(MacOSの場合、「script」の調整が必要)
:::

こんなデバッグ構成をlaunch.jsonや*.code-workspaceファイルに記述した。

```
"launch": {
	"version": "0.2.0",
	"configurations": [
		{
			"name": "【PICT】現在",
			"type": "PowerShell",
			"request": "launch",
			"script": "pict ${file} > ${fileBasenameNoExtension}_result.txt && type ${fileBasenameNoExtension}_result.txt | clip && type ${fileBasenameNoExtension}_result.txt",
			"cwd": "${fileDirname}"
		}
	]
}
```
name : わかりやすい名称を指定
type : コマンドを実行したいので一旦PowerShell
cwd ： エディタで開いているファイルのディレクトリを指定
script : commandプロパティが使えなかったので、scriptとしてコマンドを記述した。
　　　内容は以下の通り。

- `pict ${file} > ${fileBasenameNoExtension}_result.txt`
    - エディタで開いているファイルをpictコマンドに渡す
    - 実行結果を同階層の「～_result.txt」として出力(上書き)

- `{type ${fileBasenameNoExtension}_result.txt | clip`
    - 実行結果txtを読み込んでクリップボードにコピー

- `type ${fileBasenameNoExtension}_result.txt`
    - 実行結果txtを読み込んでコンソールに出力

# 挙動イメージ
1. 初期状態はこんな感じ
    - カレントディレクトリはデスクトップとする。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680589/e6fd5904-8232-8300-ba52-bb662e6dca0c.png)

1. F5でデバッグ実行
1. 実行結果はこんな感じ
    - カレントディレクトリとは無関係に、
        実行対象のpictファイルと同じディレクトリに結果が出力される
    - 実行結果が統合ターミナルにも出力される 
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680589/f8623605-0f74-e243-856a-4cf1f94e6fbf.png)


# 終わりに
便利なツールであっても認知資源が消費されやすいと、つい利用を避けてしまう。
いかにシームレスかつ気軽に利用できるようにするかが大切だ。
年末のおっさんは2画面使ってpyxelしたい

# はじめに
pyxelの設計想定外のことをしているかもしれません。あくまでネタとしてお楽しみください。

# 実行画面(出オチ)
![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309295/0d8bad7c-f509-2db2-6852-326c414d1c16.gif)


# 何をしているのか
2つのプロセスそれぞれでpyxel.run()しています。
無茶なことしたかな…と思いきや意外とすんなりいったのでびっくり。

# ソースコード解説
`concurrent.futures`モジュールの`ProcessPoolExecutor`を使用します。
```python
from concurrent.futures import ProcessPoolExecutor
```
プロセスを2つぶん用意して、`app_func_worker(0)`と`app_func_worker(1)`をそれぞれ別プロセスで実行します。
```python
        executor = ProcessPoolExecutor(max_workers=2)
        appFutures = [ executor.submit(app_func_worker,i) for i in range(2) ]
```

上記で指定した関数app_func_worker()のなかで、pyxelでは定番のApp()を呼んでいます。
```python
def app_func_worker(app_id):
    return App(app_id)
```

# ソースコード
全ソースコードはこちら。やってることの割にこのソースコードの短さ…恐るべしpython＆pyxel。
python歴まだ若いので至らないところあったらご容赦ください。
※pyxel公式のサンプルソースコード`01_hello_pyxel.py`をベースにしています。
※ウインドウが2つ重なって出てくるので手動で横に並べてね（笑）

```python
from concurrent.futures import ProcessPoolExecutor
import pyxel

WW,WH,X,Y,DX,DY = 160,120,50,50,4,4

def app_func_worker(app_id):
    return App(app_id)

class App:
    def __init__(self,app_id):
        global X,Y,DX,DY,WW,WH
        self.app_id = app_id
        self.wx = 160 * app_id
        self.wy = 0
        pyxel.init(WW, WH, title="Hello Pyxel",display_scale=2)
        pyxel.images[0].load(0, 0, "assets/pyxel_logo_38x16.png")
        pyxel.run(self.update, self.draw)

    def update(self):
        global X,Y,DX,DY,WW,WH
        if X + DX < 0 or X + DX + 38 > 320:
            DX *= -1
        if Y + DY < 0 or Y + DY + 16 > 120:
            DY *= -1
        X += DX
        Y += DY

    def draw(self):
        global X,Y,DX,DY,WW,WH
        pyxel.cls(0)
        if self.wx - 38 < X < self.wx + WW:
            pyxel.blt(X - self.wx, Y, 0, 0, 0, 38, 16)
        pyxel.text(55, 41, f"Hello, Pyxel {self.app_id} !", pyxel.frame_count % 16)

def cleanup():
    print ('** cleanup **')
    executor.shutdown(wait=True)

if __name__ == "__main__":
    try:
        executor = ProcessPoolExecutor(max_workers=2)
        appFutures = [ executor.submit(app_func_worker,i) for i in range(2) ]

    except Exception as e:
        print('エラーが発生しました')
        print(e)
        cleanup()
```



# おわりに
キーセンスはどちらの画面で拾っているかとか、pyxel.quit()すると何故か両プロセスとも落ちてくれる（これはこれでありがたい）とか、気になるところはいろいろありますが、ひとまずネタとして割り切って公開しました。
マルチディスプレイ環境で横３画面使ってダライアス（昔のシューティングゲーム）とか、タッチディスプレイ縦横９画面使ってストラックアウト（スポンジボールにしておこう）とか、夢が広がりますね！
vscodeのvimを触ってみる

この記事は釧路高専プログラミング研究部 Advent Calendar 2024の参加記事です

# はじめに
突然ですが皆さんVimを知っていますか？Vimはテキストエディタの一種で、リリースから30年以上たった今でも根強い人気があります。私はもともと自分のPCでプログラムを書く際にVSCodeを使っていましたが、学校のC言語の授業ではVimを使うことが強制され、それがきっかけでVimのキーバインドの便利さに目覚めました。が、自分のWindowsにわざわざVimを入れるのはめんどくさかったので、VSCodeでVimの操作をすることにしました。その方法やVSCodeでのVimのカスタマイズ方法を紹介していきます。

# VSCodeにVimの拡張機能を入れよう
VSCode Vimという拡張機能を入れることで、VSCode内でVimのキーバインドを利用することができるようになります。下の画像のように左のバーから拡張機能を選択し、そこの検索窓でVimと検索することでVimの拡張機能を手に入れることができます。
![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935353/9f490038-4678-5430-d5a4-8fd852816bff.gif)

# 基本的な操作方法
通常のVimと大体同じです。基本的にはhjklでカーソルを操作し、iキーなどで挿入モードに入ってから文字を打ち、ノーマルモードに戻ってキーの操作をするということの繰り返しです。わざわざモードを切り替えないと文字が打てないのは一見不便に感じるかもしれませんが、ノーマルモードでのキー操作でカーソルを動かすことで、キーボードのホームポジションからあまり動くことなく効率的にカーソルを操作することができます。vimの細かい操作方法についてはここでは触れませんので、気になる方はググってください。

# ちょっとカスタマイズ
Vimの特徴の一つにカスタマイズ性の高さがあげられます。Vimはvimscriptと呼ばれるスクリプト言語を書くことで機能を独自にカスタマイズできます。VSCode Vimの場合vimscriptで設定を書かずに(一応でvimscriptも使えるみたいです)、settings.jsonと呼ばれるjson形式のVSCodeの設定ファイルに設定を書くことで自由にカスタマイズすることができます。ここでは一部をかいつまんで紹介しますがより詳しく知りたい場合は[こちら](https://github.com/VSCodeVim/Vim "VSCodeVim/Vim: :star: Vim for Visual Studio Code")をご覧ください(英語です)。
### settings.jsonの開き方
とりあえず設定を書くためにsettings.jsonを開いてみましょう。
**1.コマンドパレットを開く**
Ctrl+Shift+Pでコマンドパレットを起動することができます。また上の検索窓に>を入力することでも同じくコマンドパレットが開きます。
![Untitled-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935353/ca0ef9a9-c5be-1b50-7607-7ad62d986739.gif)

**2.検索窓にsettings.jsonと入力**
settings.jsonと入力すると検索候補の欄にユーザー設定を開く(JSON)というものが出てきますのでそちらをクリックするとsettins.jsonが開きます。
![Untitled-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3935353/ea952c4e-3a9a-953d-545a-6e8207ded7a8.gif)

### キーバインドを変更する
VSCode Vimでは通常のVimと同じくモードごとにキーバインドを変更することができます。例えば、インサートモード時にjjと打ったらEscキーが打たれたことになってノーマルモードに戻るなどといったことが可能になります。
```
    "vim.insertModeKeyBindings": [
        {
            "before": [
                "j",
                "j"
            ],
            "after": [
                "<Esc>"
            ]
        }
    ], 
```
上記のコードをsettings.jsonに書き込むことで、インサートモード時にjjと打つことでEscが作動し、ノーマルモードに戻ることができます。beforeの部分に設定したいキーを入力し、afterの部分にその時に実行したいキーを入力する形です。また一つのモードに複数のキーバインドを設定する際にはモードごとに続けて書くことができます。
```
    "vim.normalModeKeyBindings": [
        {
            "before":["<C-t>"],
            "commands":[":tabnew"]
        },
        {
            "before":["<Esc><Esc>"],
            "commands":[":nohl"]
        }
    ],
```
この場合はノーマルモードの時にC-tを押すことで新たなタブを開くのと、Escを二回連続で押すと検索したハイライトを全てリセットするということになります。"before"の部分は先ほどインサートモードの設定をした時と文法が変わりませんが、その後の"after"だった部分が"commands"に代わっています。:tabnewや:nohlなどのコマンドラインモードでのコマンドをキーバインドに設定したい場合はcommandsで指定してあげる必要があるのです。
GCSを不変ストレージにする方法

Google Cloud Storageを不変ストレージにして、ランサムウェアによるデータ削除や内部犯によるデータ削除から守る方法を紹介します。

# 使えそうで使えない機能
まず最初に一見するとこの目的に使えそうではあるものの、実は活用できない機能(罠)を紹介します。Object VersioningとSoft Deleteです。

Object VersioningはGCSのオブジェクトを削除・書き換えしたときに古いオブジェクトを自動的に保持して復元できる機能です。この機能は偶発的なファイル削除に対しては有効に機能しますが、ランサムウェアや内部犯などの悪意を持った削除に対しては有効ではないです。
なぜなら、Object Versioningによってバックアップが取られている過去バージョンのデータを消すこともできるからです。そのため、悪意を持った犯人が過去バージョンも含めたすべてのバージョンを消してデータを完全に消し去ることができてしまいます。

https://cloud.google.com/storage/docs/object-versioning

Soft Delete機能はGCSのオブジェクトを削除したときに古いオブジェクトを一旦Soft Deleteという状態にした後、一定期間(デフォルトでは7日)経過後に本当に削除する機能です。Soft Delete状態のオブジェクトは管理者権限を持っていても削除することはできないため、一見すると不変ストレージとして使えそうです。しかし、管理者権限があればSoft Delete機能をOFFにすることができてしまうため、この方法もObject Versioningと同様に偶発的なファイル削除に対してのみ有効な方法です。

https://cloud.google.com/storage/docs/soft-delete

# Bucket Lock
GCSを不変ストレージにするためにはBucket Lock機能を使用します。この機能を使うと一定期間の間、GCSオブジェクトの削除が不可能になります。

https://cloud.google.com/storage/docs/bucket-lock

以下のようなterraformファイルでBucket Lockされたバケットを作成できます。

```tf
resource "google_storage_bucket" "immutable-bucket" {
  name     = "<BUCKET-NAME>"
  location = "US"

  retention_policy {
    is_locked        = true
    retention_period = "<保持期間を秒で指定>"
  }
}
```

Google Cloudのドキュメントでは最大で100年まで保持期間を指定できるように書いてありますが、terraformでは最大で2,147,483,647秒(約68年)までしか指定できないようです。(多分terraformのバグ?)

https://cloud.google.com/storage/docs/bucket-lock#retention-periods

https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#retention_period-1

この方法で保持期間を設定したバケット内のオブジェクトは管理者権限(Ownerロール)を使っても削除できず、バケットを丸ごと削除することも不可能です。また管理者権限を使って保持期間を短くすることもできません。

そのため、ランサムウェアなどの悪意をもった相手にプロジェクトの管理者権限を奪われてしまってもデータを守ることができます。

# 不変ストレージのデータを削除する方法
最後にこの不変ストレージのデータを削除する方法について紹介します。この方法で作成した不変ストレージはGoogle Cloudプロジェクトを削除することで削除できます。そのため、不変ストレージを確実に「不変」にするためには、この削除方法からの防御が重要になります。

まず、プロジェクトの削除権限は非常に強い権限かつ、頻繁には必要にならない権限であるため、権限保持者を限定するという対策が考えられます。更にその上でPAMなどを用いてプロジェクトの削除操作を行うために複数人の共同作業が必要になるようにすることでより強固なセキュリティを構築できます。

https://cloud.google.com/iam/docs/pam-overview

また、万が一GCPプロジェクトが削除させてしまった場合でも早期に復旧させることで被害を最小化することもできます。多くのリソースは30日以内であれば復元可能です。GCSは30日よりも早く削除されることがあるようですが、プロジェクトの削除後なるべく早くに復元させればデータ損失を免れる可能性もあります。そのため、Google Cloudの外のモニタリングツールなどでプロジェクトの削除をいち早く気付けるようにアラートを設定することも対策として考えられます。

https://cloud.google.com/resource-manager/docs/creating-managing-projects#restoring_a_project

# 消すことができるのに不変とはどういうことなのか？という考察
さて、削除可能なのに「不変」とはどういう意味なのかということに関して考察します。

まずこの世に真の「不変ストレージ」はないです[^1]。例えばオンプレ用の「不変ストレージ」として販売されている製品であっても、データセンターに侵入して不変ストレージを物理的に破壊することでデータを削除できます。もっと極端(ですが人類の実現可能な)例を考えると、不変ストレージとそのバックアップのあるすべてデータセンターに核ミサイルを同時に落とせばデータは消えてしまうでしょう。

そのため、ここで言う「不変」とは真の意味での不変ではなく、「現実的に考えれば削除できる可能性はほぼゼロに等しいと考えられる」という意味を指します。先ほどのオンプレの例で言えば、データセンターに侵入した後に物理破壊できる可能性です。不変ストレージを不変たらしめている要因は製品の仕様だけではなく、その製品の運用体制にもあります。オンプレデータセンターの入出管理が適切であればオンプレの不変ストレージは不変であるのと同様に、GCPのプロジェクト削除権限の管理が適切であればGCSの不変ストレージは不変になります。

[^1]: 理論物理学の極北のような、一般人にはSFと現実の間に見えるような領域にはあるかもしれませんがこの記事では考えません
アウトプットについて考える

お疲れさまです、みやもとです。

今年は我ながらいろいろアウトプットしたと思います。
がんばりました。

がんばったのですが、やってみてそれぞれの方法に「向いてる」「向いてない」「ここは良い」「ここはちょっと」と、いろいろ感じるところがありました。
なので今日はそれをちょっとまとめて書いておこうと思います。

# アウトプットの方法について
あくまで私の場合ですが、インプット・アウトプットどちらも基準は「私個人」を境界として考えています。
特にアウトプットについては多くの場合「誰かに対して発信すること」という前提で書かれているように思うのですが、私個人の行動としては「とにかく私の頭の中から外に出したらその時点でアウトプット」としています。
私以外の誰ひとりとして見ていなかったとしても、コード1行でも書いていれば私にとっては「アウトプット」とします。

## LT（オンライン）
YouTubeやZoomで登壇する。
担当時間は質疑応答含めて10～20分ぐらいにおさめることが多いです。

メリット：
* 顔出ししなくていい
* 聞いている人を視覚的に意識しなくてすむ（＝多少緊張が和らぐ）

デメリット：
* 場合によってはアーカイブが残る（＝上手くしゃべれなかった場合にちょっと恥ずかしい）
* 会場の反応等によって内容を調整するのが難しい

## LT（オフライン）
イベント会場に足を運んで登壇する。
こちらも担当時間は10～20分ぐらいが多いですが、場合によってはもっと短くも長くもなります。

メリット：
* 会場の雰囲気を感じながらしゃべる内容を微調整できる
* アーカイブが残らない（＝勢いで乗り切った後振り返らずに済む）

デメリット：
* 顔出しがほぼ必須[^1]
* 聞いている人を視覚的に意識することになる（＝緊張度アップ）

[^1]:プロレスマスクをかぶる等で顔出し回避していた人もいましたが、私がやるとしたら何を使うか？と考えると実行はなかなか難しい気がします。

## Web記事投稿
QiitaやZenn等、記事を書いて公開する。
記事の長さは人それぞれですがコード例とか含めると1000以上になることがほとんど？

メリット：
* 書く内容を推敲してじっくり取り組める
* 好きなテーマで書ける

デメリット：
* 「これは本当に記事にするようなことか？」と悩みだすと止まらない
* 書いたことが残るので間違いとか不適切な記述があると大変申し訳ない

## ハンズオン
本や動画、Web記事を読んで何か作ってみる。
シミュレータで1行コードの実行から実際にプログラム作成して動作させたり、難易度も手軽さも様々です。

メリット：
* 実際の動作を見て理解度を深められる
* 完全に自己完結なので人目を気にせず楽しめる

デメリット：
* 完全に自己完結なので外部へのアピールに欠ける
* 動かす楽しさを優先して理論が置いてきぼりになることがある

# 自分に合うアウトプットの方法は？
私がアウトプットする時に重視するのは

〇私が楽しいか
△見た人が楽しめるか
✖たくさんの人に見てもらえるか

という感じなので、先述したアウトプットの方法でならWeb記事やハンズオンが良いかなという結論になりました。
とはいえLTにも交流のとっかかりになったりほかにないメリットはあるので、無理のない範囲で続けていけたらと思います。
【Next.js15×Auth0】[Error: Route "/api/auth/[auth0]" used params.auth0. params should be awaited before using its properties. 

2024/12/15現在、Auth0のメジャーバージョンではNext.js15対応ができていないため上記エラーが発生する。
## 対処方法
### コード
ベータ版（@auth0/nextjs-auth0@4.0.0-beta.0）を使用する。

```
npm i @auth0/nextjs-auth0@4.0.0-beta.0
```

以下のファイルをプロジェクトルートに追加する

```typescript:middleware.ts
import type { NextRequest } from "next/server"

import { auth0 } from "./lib/auth0"

export async function middleware(request: NextRequest) {
  return await auth0.middleware(request)
}

export const config = {
  matcher: [
    /*
     * Match all request paths except for the ones starting with:
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico, sitemap.xml, robots.txt (metadata files)
     */
    "/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
  ],
}
```

プロジェクトルートにlibディレクトリを作成し、以下のファイルを追加する。
```typescript:lib/auth0.ts
import { Auth0Client } from "@auth0/nextjs-auth0/server"

export const auth0 = new Auth0Client()
```

ログインボタンのリンク先を下記に変更。
```html
<a href="/auth/login">xxx</a>
```

ログアウトボタンのリンク先を下記に変更。
```html
<a href="/auth/logout">xxx</a>
```

### Auth0側の設定
アプリケーションはRegular Web Applicationを使用し、設定を下記に変更する。
- Allowed Callback URLs: http://localhost:3000/auth/callback
- Allowed Logout URLs: http://localhost:3000
- Allowed Web Origins: http://localhost:3000

## ログイン後のリダイレクト設定
先ほど作成したAuth0のクライアントをカスタマイズする。
以下はログイン後のリダイレクト先を/homeに設定している。
```typescript:lib/auth0.ts
import { Auth0Client } from "@auth0/nextjs-auth0/server"

export const auth0 = new Auth0Client({
    signInReturnToPath: "/home",
})
```

## 参考
https://www.npmjs.com/package/@auth0/nextjs-auth0/v/4.0.0-beta.0
エンジニアの首は左にねじれすぎている

## はじめに

いきなりタイトルの回収します

エディタでファイルを開く時って表示が左寄せになりますよね？
その上テキストも左寄せなので、それを読み書きするエンジニアの首は**無意識的に左に傾いてしまう**のです
エンジニアに特有の身体的傾向ですね

本記事ではそれを解決するためのプラグインが結構便利そうだったので紹介します！！！

なお、本記事で紹介するプラグインはneovimのプラグインになります
VSCodeをご利用の方は、zen-mode🧘を使ってみてください！
デフォルトで入ってるので、コマンドパレットからどうぞ💁

https://code.visualstudio.com/docs/getstarted/tips-and-tricks#_zen-mode

では、本題いきます

## プラグインについて

no-neck-painというプラグインです

https://github.com/shortcuts/no-neck-pain.nvim

### install & config

lazy使ってるのでlazyのインストール方法です

```lua
return {
	"shortcuts/no-neck-pain.nvim",
	version = "*",
	config = function()
		require("no-neck-pain").setup({
			buffers = {
				right = {
					enabled = false,
				},
				scratchPad = {
					enabled = true,
					location = "~/notes",
				},
				bo = {
					filetype = "md",
				},
			},
			autocmds = {
				enableOnVimEnter = true,
				enableOnTabEnter = true,
				reloadOnColorSchemeChange = true,
			},
		})
		vim.keymap.set("n", "<leader>z", "<cmd>NoNeckPain<CR>")
	end,
}
```

#### `buffers.right.enable`

no-neck-painを有効にした時、デフォルトの設定では画面両サイドにbufferが出現します
そしてそれらのbufferはscratchPadと言ってメモのように活用できるのですが、右のbufferは持て余すので無効にしてます

#### `buffers.scratchPad`

サイドbufferをscratchPadとして使うための設定です
サイドbufferで開くファイルの保存先pathを指定できます
`no-neck-pain-left.md`,`no-neck-pain-right.md`っていうファイルが生成されてそれが表示される仕組みです

#### `buffers.bo`

サイドbufferのoptionです(**b**uffer **o**ption)
サイドbufferで開くファイルタイプを指定します
筆者はちょっとしたタスク管理やメモとして使いたいので`md`を指定しました

#### `autocmds`

ファイルを開いた時に自動的にno-neck-painを有効にするための設定です
`reloadOnColorSchemeChange`はいらないっちゃいらないですが、筆者は気分でカラースキーマコロコロ変えるので有効にしてます

#### `vim.keymap.set("n", "<leader>z", "<cmd>NoNeckPain<CR>")`

`z`にkeybindしているのは、元々zen-modeのトグルを`z`にバインドしてたからです
それだけです

### 使用感

![スクリーンショット 2024-12-15 17.16.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2947418/6a3e83bb-4003-54de-1467-ff549c9d10b4.png)

上記の設定でファイルを開くとこんな感じになります
まずやはり注目すべきは表示位置ですね。ちゃんと中央にいってます。

で、個人的にサイドbufferをメモとして使えるのが結構便利だと思いました
この記事はサイドbufferで書いてます

### zen-modeとの比較について

個人的にはno-neck-painの方が使いやすいと感じました

|                  | zen-mode      | no-neck-pain  |
| ---------------- | ------------- | ------------- |
| 複数window       | x             | o             |
| buffer分割時     | x(無効になる) | o(有効のまま) |
| サイドbuffer活用 | x             | o             |

## 最後に

いかがでしたか
色々と痒いところに手の届くプラグインだなって思いました！
gitHubのREAMEに色々とカスタマイズ例もあって楽しいのでぜひ見てみてください！

再掲

https://github.com/shortcuts/no-neck-pain.nvim
文系大学生がエンジニアっぽい何かになろうとした②

## 僕と試験と42〜1次試験〜
さて、前回の記事でエンジニアという単語と出会った訳ですが、ここからが正念場です。

42Tokyoを知ったはいいものの、ここに入学するまでには2つの試験を突破する必要があります。
今回はその一つ目について軽くお話ししましょう。

42Tokyoの1次試験はエンジニア適性検査的なやつです。
この字面を見た瞬間、おわった、と思いました。

それもそのはず、僕は生粋の文系なので「適性検査」とか言われたら

***「適性なんてある訳ないだろ！　こちとら数学20点ぞ！？」***

となる訳です。

ともあれ、受けないことには始まらないのですが、僕はしばらくこの1次試験を***受けませんでした。***

理由はふたつ。

１　難しそうなので対策をしたかった
２　スケジュール的に調整をつけるのが難しかった

１に関してはネット上で情報を集めようとしたのですが、そんなに有益なものは見つからなかった気がします。（探し方が悪かっただけかも）

２に関しては、ぶっちゃけこれが一番大きな理由です。「なんやかんや3時間くらいはかかる」みたいなことが書いてあったので、万全の状態にするためにも静かな場所と、充分な時間が欲しかったのです。

そんなこんなで、結局1次試験を受けたのは、42Tokyoと出会って半年後でした。

## 僕と試験と42〜2次試験〜

1次試験の内容は伏せますが、割合の計算が時々できなくなる僕でも***突破できた***、とだけお伝えしておきましょう。

1次を突破したのはいいものの、次は2次試験。
ピシンと呼ばれるこの試験はなんと一ヶ月もの期間を要します。

僕は当初からこの試験にフルコミットするつもりでした。フルコミットする理由は以下の通り。

１　完全初心者で、（多分）誰よりもスタートが遅れているから
２　仲良くなる時間をとりたい

おそらく応募者の中で誰よりもできない自信がありました。
だって数学も物理も、ひいては算数すら怪しい僕です。
応募者は理系が多くなりそうだし、きっとみんな微積が出来る側の人間でしょう。
そうなれば僕は誰よりも勉強しなくちゃいけません。

あとは、この試験の中で何か一つでも爪痕を残せるところが必要だと思いました。
そうして僕が導き出したのが

***とにかく時間で殴る***

でした。
とにかくフルコミットして誰よりも試験に関わる。
そして参加者全員と仲良くなって、もしかしたら「あいつと一緒に入学したいから助けたろ」みたいなことにならないかなぁ……。といった甘い幻想を抱いていたわけです。

以上の理由によって、ピシンを受けるのは夏か冬の長期休み期間のどちらかです。
1次を突破した時点で夏休み終盤だったので、準備するためにも冬休みに受けることにしました。

こうして、42Tokyoと出会ってから約1年の時を経て、ついに42Tokyoの門をくぐる日がやってきます。

続く
React　onClickの発火発火タイミングについて

アプリ開発中onClickの発火タイミングについて理解不十分により意図しない挙動がされたため、注意点を共有させていただきます。

```.jsx
const onClickDelete = () => {
  console.log("削除ボタンがクリックされました");
};

<button onClick={onClickDelete}>削除</button>
```
上記だとクリックしないと発火しません。

```.jsx
const onClickDelete = (index) => {
  console.log(`削除ボタンがクリックされました: ${index}`);
};

<button onClick={onClickDelete(1)}>削除</button>
```
上記だとボタンが生成された時点で発火してしまいます。

違いは（）の位置。onClickDeleteという関数に()が付いているとonClickDeleteをすぐ実行してonClickに結果を渡すとReactが解釈してしまうため、クリックとは関係なくonClickDeleteが実行されてしまいます。

```.jsx
const onClickDelete = (index) => console.log(`削除されました: ${index}`);

// 無名関数を渡している
<button onClick={() => onClickDelete(1)}>削除</button>

```
上記のように無名関数（アロー関数）を使用すれば関数を定義しているだけになり、onClickDeleteに（）が付いていても発火はクリックした時だけになります。

# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてください！
▼▼▼

https://projisou.jp
「SyntaxError: "undefined" is not valid JSON」の解決方法 ChakraUI Jest React.js TypeScript

# はじめに
設定系、config系ファイルにもっと慣れる必要があります。

# 問題
5日前まで通っていたテストが通らなくなりました。

```
% npm run test

> sample-vite-ts@0.0.0 test
> jest

  console.error
    Error: Uncaught [SyntaxError: "undefined" is not valid JSON]


~~中略~~

 FAIL  src/tests/AppComponent.spec.tsx
  title
    ✕ should render title (84 ms)

  ● title › should render title

    SyntaxError: "undefined" is not valid JSON
        at JSON.parse (<anonymous>)

      21 |
    > 22 |   return JSON.parse(JSON.stringify(obj));
         |               ^
      23 | };
      24 |
      25 |
      
      at Object.<anonymous>.global.structuredClone (jest.setup.ts:23:15)
~~省略~~
```


# 解決方法
```jest.setup.ts
import '@testing-library/jest-dom';

require('dotenv').config();

global.structuredClone = (obj) => {
// console.log("jest.setup.ts", obj); // 確認用で追加
// if (obj === undefined) console.log("jest.setup.ts undefined", obj); // 確認用で追加
if (obj === undefined) return undefined; // 追加
  return JSON.parse(JSON.stringify(obj));
};
```

@Sicut_studyに、解決方法を教えてもらいました。
以下を追加すれば良いとのことでした。

```jest.setup.ts
if (obj === undefined) return undefined; // 追加
```

が、自分なりに解決できるようになる必要があると考え、解決できる方法を追ってみました。
しかし、ドキュメントを調べたり(Jest, TypeScriptなど)、「SyntaxError: "undefined" is not valid JSON」で検索したりしてみたのですが、解決方法が見つかりませんでした。

ふと、jest.setup.tsにconsole.logを仕込んだらどうなるのだろうと思いついて、やってみました。
(jest.setup.tsが問題点であることは、エラー文に出ている、return JSON.parse(JSON.stringify(obj))で検索すればわかります。また、エラーの下にあるstack traceを見てもわかります。)
```
if (obj === undefined) console.log("jest.setup.ts", obj);
```
上記を仕込んで、testを実行。
```
% npm run test

> sample-vite-ts@0.0.0 test
> jest

  console.log
    jest.setup.ts undefined

      at Object.<anonymous>.global.structuredClone (jest.setup.ts:21:34)

 PASS  src/tests/AppComponent.spec.tsx
  title
    ✓ should render title (665 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.861 s, estimated 4 s
Ran all test suites.
```

エラーはこれだけでした。
これであれば、if (obj === undefined) console.log("jest.setup.ts", obj); を仕込めば解決できることに合点がいきました。

# おわりに
setup系ファイルに、console.logが仕込めるのは盲点でした。
エラーがどこで起きているのかの確認と、console.logで何が起きているのかを確認することが大事だと思いました。
はじめてアドベントカレンダーに参加しました / I participated in an advent calendar for the first time (日本語 / 英語)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812041/b0eba4f3-08f8-e14f-fc98-b8565b7d5d42.png)
# 日本語
こんばんわ！
Advent Calendar 2024に参加してまして、15日目の記事を書いていこうと思います。
題材は「はじめてのアドベントカレンダー Advent Calendar 2024」ということで、今回初めてこのイベントに参加しているのですが、そのことについて記載していきます。

### Advent Calendar 2024に参加したきっかけ
まず、Qiita自体は登録していて、調べもの等で使用させていただいてたのですが、あまりブログを書いたりと積極的に活用するというレベルではありませんでした。
そんな中、今年からQiitaでブログを書いていこうと思って書いていってたらハマってしまい、そんなハマっている状態でこんなイベント知ったら参加するしか選択肢ありませんよね！！

ただ、初めての参加ということでルールをあまり知らず、ためていた記事をフライングで投稿するということをしてしまいました。申し訳ないです。
※修正しました

### Advent Calendar 2024で達成したいこと
とりあえず、25日連続投稿は目指しています！
この記事で15日連続投稿中なのであと10日間ですかね。
とても大変ですが、達成した先にはきっと何かあると思って頑張っていこうと思ってます。

ここまで読んでいただきありがとうございます。

# ENGLISH
Good evening!
I am participating in Advent Calendar 2024 and I am going to write an article for the 15th day.
The subject is “My First Advent Calendar Advent Calendar 2024,” so this is my first time participating in this event, and I will describe about it.

### How I got involved in Advent Calendar 2024
First of all, I have registered for Qiita and have been using it for research and other purposes, but I have not been actively using it for blogging or other purposes.
I was not at the level of actively using Qiita for blogging, but this year, I decided to start blogging on Qiita and got hooked on it!

However, since it was my first time to participate, I didn't know much about the rules, and I had to submit my hoarded articles in a flying start. My apologies.
I have corrected it.

### What I want to accomplish in Advent Calendar 2024
For now, I am aiming to post for 25 consecutive days!
I am posting 15 days in a row with this article, so I guess I have 10 days to go.
It's a lot of work, but I'm sure there will be something beyond this achievement, so I'm going to do my best.

Thank you for reading this far.
TCPコネクション解放

# FINが流れるとその方向のコネクションが閉鎖される
>各コネクションはもう一つのコネクションとは独立に解放される。コネクションを開放するために、両端ともこれ以上送信するデータがないことを示すFINビットを設定したTCPセグメントを送る。FINが確認通知されると、その方向のコネクションは、閉鎖され、これ以上データが流れることはない。逆方向のコネクションのデータはそれとは無関係に流れ続けることができる。両方向が閉じられると、コネクションは解放される。

# コネクションの開放には四つのセグメントを使う
>通常、コネクションの開放には四つのセグメントをが必要とされる。両方向のコネクションでそれぞれ、一つのFINと一つのACKが送られる。ただし、最初のACKと次のFINが同一のセグメントに含まれ、全体で三つのセグメントをになることもある。

# FINに対する応答が最最大パケット生存時間の2倍以内にないとコネクションを開放する
>二つのホストがコネクションを同時に解放するのか、順番に開放するのかということに本質的な違いはない。

>二つの軍隊問題を避けるために、タイマーが利用される。FINに対する応答が最大パケット生存時間の2倍以内にない場合、FINの送信者はコネクションを開放する。

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/

# 感想
コネクションを確立させて確認とともにFINを送って開放
素のPHPで理解する絶対PATH 相対PATH

## はじめに
今回は素のPHPでアプリ開発をしている際に発生した相対PATHによるエラーです。
高機能なフレームワークを使用していると、実行したスクリプトの場所によるエラーが発生しないので、はまりポイントだなと思いました。

## ファイル構造
以下のような構造のプロジェクトがあるとします
```
app/
  src/
    - main.php
    - sub.php
```

## 相対PATHとは?
現在のファイル(カレントディレクトリ)から見た相対位置で指定
```php
// main.php
require './sub.php'
// ./ 同じディレクトリ
// ../ 1つ上のディレクトリ
```
## 絶対PATHとは?
ルート(一番上の階層)からのフルPATH
```php
// main.php 
// __DIR__は現在のファイルまでのPATHが入ります。
require __DIR__ . '/sub.php';
```

index.php
```php
require './sub.php'
```
この時上記は正しく機能します。index.phpはsub.phpと同じ階層です。

## エラーが発生する例
構造を少し変えます。
```
app/
  src/
    - main.php
    - sub.php
  dir/
    - add.php
```

add.phpからmain.phpを読み込んでみます
```php
require '../main.php'
```

main.phpを開いた時、つまり 
localhost:8000/main.phpでエラーは発生しません。
localhost:8000/dir/add.phpを開いた時にエラーが発生します。




add.phpが起点になります。main.phpの読み込みには成功しますが、main.phpの内の`require './sub.php'`でエラーが発生します。

これは実行されたスクリプトがadd.phpなので、カレントディレクトリはapp/src/dir/になります。
main.php内の`require './sub.php'`は実際にはこのような構成を期待します

```shell
app/
  src/
    - main.php
  dir/
    - add.php
    - sub.php # sub.phpがこの位置にいることを期待
```

このように相対PATHが起点とするカレントディレクトリは実行されたスクリプトの位置によって決まるため、思わぬバグを引き起こす可能性があります。

ちなみにこの例では以下のようにするとエラーが発生しません

### 絶対PATHを使用する
rootから見たsub.phpの位置をフルPATHで指定します。
この方法が一番確実です.

```php
// main.php
require __DIR__ . '/sub.php'
```

### PATHの書き方を変える
この方法は挙動が複雑で、お勧めしません。
```php
// main.php
require 'sub.php'
```

PHPは以下のような順序で探索を行います。
- 1 インクルードパス
- 2 カレントディレクトリ（実行ファイルのディレクトリ）
- 3 その親ディレクトリをrootにたどり着くまで順に探索

ポイントはカレントディレクトリはapp/src/dir/addですので、変わらずdir/配下にsub.phpがあることを期待しますが、存在しなかった場合、親ディレクトリを探索、そこでも見つけられない場合は、更に親ディレクトリを探索するという挙動です。

localhost:8080/dir/add.phpを開いた時、結果的に以下のような状態になります。
```shell
app/
  src/
    - main.php
    - sub.php # カレントディレクトリに存在しない場合この位置で探索にヒット
    dir/
      - add.php
      - sub.php # main.phpのrequireはsub.phpがこの位置にいることを期待
      dir2/
        - sub.php # この位置は探索しない
    hoge/
      - sub.php # この位置は探索しない
```

大分複雑ですね。

このような問題を抱えてしまうため、絶対PATHを使用するのが良いと思います。

## 終わりに
モダンな開発で使われるフレームワークでは、相対PATHで記述しても、上記のような問題が発生しないような仕組みが備わっています。 先人に感謝を
そして、フレームワークを使う時に相対PATHで書くこともあると思いますが、このような前提を体験すると、絶対PATHで統一したくなっちゃいますね。
フレームワークを使わない開発を体験してみて、大きな発見でした。
Container/Presentationalパターンを今更知ったのでNext.jsのApp Routerで学び直す

偶発的な出来事によりフロントエンドを始めて1年ちょっとが経ちましたが、全然わからないまま日々実装している毎日です。  
ひょんなことから「Container/Presentationalパターン」を知ったのでそれについてNext.jsのApp Routerとの親和性が高そうだと感じたのでちょっとだけ考えてみます。※ほぼ備忘録です。

まあ、私が詳しく書かなくとも以下の記事ですごく丁寧に説明されていますのでこれだけでOKな方はぜひ参照してください。

https://zenn.dev/akfm/books/nextjs-basic-principle/viewer/part_2_container_presentational_pattern#%E5%BE%93%E6%9D%A5%E3%81%AEcontainer%2Fpresentational%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3

またClient ComponentやServer Componentなどの概念の説明は省略しているのでご了承ください……。

## Container/PresentationalパターンはApp Routerとの親和性が高い

言いたいことはほぼこれだけです。

App Routerでは Client と Server でコンポーネントを分けることができます。ファイル名の先頭とかに `use client` や `use sever` をつけることで、クライアント側のコンポーネントなのかサーバー側のコンポーネントなのかを位置づけることができます。

特になにもしないと普通に以下のエラーを吐くので、Next.jsのApp Routerを使う人は誰しもが気付かされるでしょう。

> ReactServerComponentsError:
>
> You're importing a component that needs useState.
> It only works in a Client Component but none of its parents are marked with "use client",
> so they're Server Components by default.

さらに適当に `use server` を使おうとして以下のエラーが出て「なんやねん」となるはずです。

> It is not allowed to define inline "use server" annotated Server Actions in Client Components.

これら2つのエラーにより、開発者はわりと厳密に `use client` と `use server` の使い分けのルールを守る必要が出てきます。

で、このルールがそのまま「Container/Presentationalパターン」に適用できるわけです。


### Container

Containerはデータ取得しそれをPresentationへ渡す役割です。つまりApp Routerでいうところの __Server Component__ と似てます。

より厳密にClientと関心事を分離するために `import 'server-only'` を使ってもいいですね。

参考：

https://nextjs.org/docs/app/building-your-application/rendering/composition-patterns#keeping-server-only-code-out-of-the-client-environment

### Presentational

こちらは従来どおりのReactコンポーネントです。App Routerでは __Client Component__ という名前になってます。

見た目上の振る舞いや状態管理（useEffect、useHook、useState）を管理するコンポーネント群です。

## アーキテクチャ設計

個人的にこんな感じにすると良いかもと思っているアーキテクチャのイメージ図としては以下のとおりです。ディレクトリ構成ともうまくマッチさせることができそう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11128/1fa2984b-3513-fbb1-3d06-e42cd68847d5.png)

- Client Component: use client
- Server Component: use server
- Server Action: import 'server-only'

Server Componentという概念が生まれてくれたおかげで、ビジネスロジックを Client Componentからなるべく排除することができます。
個人的にStorybook駆動でのUIコンポーネント開発に懐疑的だったのは、状態管理という名目で多くのビジネスロジックを肩代わりしていたUIコンポーネントに対して、必要十分なテストを書くことのメリットをあまり感じていなかったからです。

しかし、Server ComponentのおかげでビジネスロジックをUIから切り離すことが割と簡単にできるようになった（ついでにブラウザ側からそれらを秘匿できるようになった）こともあり、App Routerによる開発であればStorybook駆動開発ももう少し楽になるんじゃないかと期待しています。

Server Actionについては言わずもがなです。APIを叩いてデータ変換する部分なので、DTOとしての役割も担えそうです。Next.jsでDDDも従来よりやりやすい気がします。

全体的に責任（関心事）の所在がディレクトリ単位でも分割できるので、テストも書きやすそう。


## まとめ
Next.jsのApp Routerのアーキテクチャやディレクトリ設計に悩んでいた方、是非Container/Presentationalパターン使ってみてください。
【Next.js14】4種類のキャッシュ まとめ

こんにちはNaotoです。

Next.jsを学ぶ中で、キャッシュについての理解を深めるために、学んだ内容をまとめてみました。

自分用にまとめたものですので、間違っている部分がありましたら、申し訳ありません。

その際は、ご指摘いただければと思います。

インプットは以下です。(ShinCodeさんの動画は本当に最強です。)

https://youtu.be/Ca1h3KUfQ5k?si=DgsMu03H667r--DE

https://nextjs.org/

では、早速4つのキャッシュについてまとめていきます。(箇条書きすみません。)

## 1. Request Memoization　（サーバー側のキャッシュ）

- 特になにも設定しなくても、Next.jsが自動で行ってくれる、リクエスト結果のキャッシュ。
- 1回のレンダリング期間中にサーバーにて作成/破棄される、ユーザー（デバイス）ごとのキャッシュ。
- このキャッシュがあることで、同じリクエスト（URLとオプションが一緒の場合）を重複排除できる。
    - 個々のコンポーネントで個別にリクエストを行ってもパフォーマンスが悪くならない。(AppRouterで推奨されている末端コンポーネントでのデータ取得に適している。）
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/d9612f86-fb95-b75a-7ff7-7b55d64a0d8d.png)

    - リクエストの結果がサーバー側にキャッシュされるため、重複を排除できる。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/057880c0-cbb7-9d60-a49f-0c0795c0de17.png)

    
- ServerComponentで`fetch()`かつGETを使う場合のみ適用される。
    - ORM等、`fetch()`以外を使う場合は、React Cacheにて対応する必要がある。
    <br>
- データ取得を行う処理は、データ取得層（DAL : Data Access Layer）に分離しておくと良い。（URLの一致が保証されるため。）

## 2. Data Cache　（サーバー側のキャッシュ）

- revalidateしない限り残り続けるキャッシュ。
- ページ全体のキャッシュ。
- `fetch()`に対するキャッシュ。JSON形式のレスポンスが、CDN（エッジサーバー）にキャッシュされる。
- `fetch()`　の引数でData Cacheの設定ができる。
    - `fetch(”https://…”, {cache: “force-cache”})`
        - Data Cacheにキャッシュされる。永続的に残る。
    - `fetch(”https://…”, {cache: {next: {revalidate: 3600}}})`
        - Data Cacheにキャッシュされ、revalidateに設定した期間後にキャッシュが破棄される。
    - `fetch(”https://…”, {cache: “no-store”})`
        - Data Cacheを使用しない。Request MemoizationでHITしない場合、直接Data Source（オリジンサーバー）にアクセスする。（毎回最新のデータが返ってくる。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/e3fb085d-9210-fe54-083a-54864397607c.png)


- prismaを使って直接データを取得する場合は、デフォルトでno-storeになる。
    - Data Cacheを使用したい場合は、RouteHandlerを介して`fetch()`で呼びだすか、`unstable_cache`を使用する。
    

## 3. Full Route Cache　（サーバー側のキャッシュ）

- Static Renderingの時のみ適用されるキャッシュ。
- ページ全体のキャッシュ。
    - 静的部分（HTMLやRSC Payload）がキャッシュされる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/9d8f0f67-3249-05d0-03db-ec8e55216b25.png)

## 4. Router Cache　（クライアント側のキャッシュ）

- ナビゲーション用のキャッシュ
- クライアント側のメモリ内にキャッシュされる。
- ページを訪問するとRSCペイロードが自動的にキャッシュされる。（静的動的問わず）
- Linkコンポーネントが画面上に現れた際は、事前に（訪問を待たずに）静的部分のRSCペイロードがキャッシュされる（プリフェッチ機能）
    - 動的部分はプリフェッチできないため、代わりに`loading.js`や`Suspense`のfallback UIがキャッシュされる。
- キャッシュ期間は、セッション中のみ。
    - 静的ページ　→ デフォルトで5分間。
    - 動的ページ　→デフォルトで30秒。
    - staleTimesでデフォルト時間は変更可能。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817219/6bd1b932-0027-e06b-a5ac-54dd95ef6219.png)

## キャッシュを無効にする

- Server Actions
    - `revalidate Path()` / `revalidate Tag()`
    - `cookies().set()` / `cookies().delete()`
- `router.refresh`


## まとめ


今回の記事は以上です。

最後までお読みいただきありがとうございました！
(理系フリマ(5))シンセ先輩からもらったCore 2 duoでArduino UNO3をLチカ(5)(最終章


参考




![o_coq690.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e5e7fb31-0c24-b96b-3a66-e30b1ced32fb.jpeg)




https://github.com/arduino/arduino-ide/issues/2429#issuecomment-2099775010


https://scrapbox.io/KusattemoToFu/Ubuntu_24.04_LTS%E3%81%A7AppImage%E3%81%8C%E5%8B%95%E3%81%8B%E3%81%AA%E3%81%84


目的
砂場の起動がセキュリティ関連で失敗するのでなんとかする

いろいろ
もうすこし、かかると思ったがなんとなくできた
(ちからつきた)
これからは、君たち時代だ!!!
(なげた)



結果　成功
----------------------------------


![o_coq689.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6c2a8a57-9816-528f-8012-b23e484f5614.jpeg)


手順
----------------------------------

ディレクトリーの移動

```

cd /etc/apparmor.d

```

セキュリティーファイルの作成
(ほらほらviだよ　徹底的に子指をいじめるんだ)


```

sudo vi arduino

```

セキュリティーファイルの内容

```

abi <abi/4.0>,
include <tunables/global>
profile arduino /home/user1/arduino/arduino-ide_2.3.4_Linux_64bit.AppImage flags=(unconfined) {
  userns,
  include if exists <local/arduino>
}

```



セキュリティーサービスの再稼働


```

sudo service apparmor reload

```


Arduino IDEの起動

```

cd

```

```

cd arduino

```


```

./arduino-ide_2.3.4_Linux_64bit.AppImage

```
ArcブラウザでTLS証明書の詳細を確認しようとしたけど、うまくいかなかった話

最近Arcブラウザっていう比較的新しいブラウザを教えてもいました
しかしTLS証明書の詳細の開き方がわからず、海外記事を気合で読み漁り、模索しているところです
All Englishなドキュメントはできるだけ読みたくないので、未来の自分のためにここにまとめようと思います

# 公式ヘルプをチェック

まずはArcのヘルプセンターから情報を探してみます
開くと大きく

- Getting Started
- Features
- Troubleshooting

とありました

が検索フォームがあったのでこの3つは無視して検索します
"cert"とかで検索すれば出てくるだろうと踏んでいたのですが、一致するものはありませんでした
"TLS"、"SSL"等関連するワードでもめぼしいものは無く
細かく見ても、近しいものはありませんでした

# 仕方ないので英語で検索
海外発の情報を漁っていくとReddit[^1]とYoutube[^2]から有力情報を得ました
[^1]: https://www.reddit.com/r/ArcBrowser/comments/16rul9p/website_httpsssl_status_missing_in_arc/?rdt=47169
[^2]: https://www.youtube.com/watch?v=UL554VF_3c4

どうやらURLが表示されている部分の右側すぐのところにある、設定アイコンのようなものに隠れているようです
押すと左下の方に見慣れた鍵マークと"secure"という文字が
更にここを押すと証明書の詳細が見れるようです

# 解決？

redditにもあったように設定アイコンみたいなものを押すと、左下に見慣れた鍵マークと"secure"という文字がありました
なんですがなぜか押しても反応せず......

他に情報を探ってみるもそれらしいものを見つけられませんでした
解決策が見つからなさそうな雰囲気がするので、一旦公式に問い合せて結果を待つことにします

続きは問い合わせの結果がまとまり次第、更新するはずです
WSL2環境のnpmでファイル監視したい場合はnodemon使え

# nodemon

```
$ npm install nodemon --save-dev
```

```
$ nodemon -L --watch 監視したいフォルダ --ext 監視したいファイルの拡張子（CSV） --exec \"実行するnpmコマンド\"
```

```json:package.json
{
  "name": "myproject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "nodejs build.js",
    "watch": "nodemon -L --watch src --ext js,css,html --exec \"npm run build\""
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "nodemon": "^3.1.9"
  }
}
```
DiscordBOT作ってみた！！

## はじめに
この記事は「[みらいサーバー アドベントカレンダー2024 3日目](https://qiita.com/advent-calendar/2024/mirai-server)」の記事です。
みらいサーバーで、高専生に無償でサーバーを貸し出していると聞いてせっかくならBOTを作ろう！ってなったのが事の始まりです。今回の記事では、そのBOTの説明とみらいサーバーの使いやすさについて考察していきます。

## 1. どんなBOT作ってるの？
学生の皆様に使っていただけるような**学生**向けの**gakuseiBOT**を作成しています。
クイズコマンドをはじめグローバルチャット機能,検索機能,名言機能など、友達で楽しく使用していただける機能をご用意しています。
開発者やDiscordのサーバー管理者向けのコマンドもあります。
もちろん学生の方以外にも使用していただけるBOTとなっています。
gakuseiBOTの開発やサポートを行うために公式Discordサーバーとホームページを掲載しておきます。(ただの宣伝です)

gakuseiBOT公式ホームページ
https://gakuseibot.pkopko.jp

gakuseiBOTコミュニティ
https://discord.gg/xaSYvUbAj5

## 2. 運用方法
### 1 環境について説明
#### 使用サーバー
・みらいサーバー
#### 開発言語
・Python
#### データ保存方法
・JSON(今後MySQL等に移行したい)

みらいサーバーを使用し、24時間常時運用しています。

### 2 SSH接続方法

詳しく説明されているので今回は書きません。
「[みらいサーバー アドベントカレンダー2024 1日目](https://qiita.com/Crysta1221/items/ad784a7aeca50c48b0d6)」
この記事で紹介されています。

### 3 使用しているアプリケーション
私が開発の際に使用しているアプリケーションを紹介したいと思います。(紹介するといっても皆さんがよく知っているものかと思います。)

・WinSCP
・PuTTY
・VSCode

今ここに記載したものだけでBOTは作成できます！
簡単にできること使用中の操作感についてまとめます。

### ・WinSCP
これは、クラウドサーバー内のファイルを整理するときに使用します。
操作感はファイルマネジャーに似ていて、とても操作しやすいです。
初心者の方でも迷うことはないかと思います。

### ・PuTTY
これは、サーバーのターミナル(コマンドプロント)に接続するときに使用します。
操作方法は、普通のターミナルですが少し操作が分かりにくいところがあるかもしれません。

:::note alert
みらいサーバーは、初期設定でパスワード入力によるSSH接続が許可されていないので、シングルコントロールパネルでConfigの設定を変更する必要があります。
:::

### ・VSCode
これは、プログラムを書くときに使用します。
このアプリが一番大切ですね。
開発を始めたいけど何をしたらいいかわからないという方は、とりあえずVSCodeをインストールしましょう。
コードの文法ミスや定義ミスなど一目でわかるように表示していけるので、コードがすごく書きやすくなります。
もうわかりまもしれませんが、操作感は最高です。
使ったことがないよって方は、一度使ってみてください。

## 3. 運用してみて
皆さんこれが一番気になっていると思います。
一言でいうと何の問題もなく運用をすることができます。

gakuseiBOTコミュニティは2024年10月4日から運用を開始しました。当時は、自宅のPCを使用していたので24時間稼働はできませんでした。
その後、みらいサーバーを利用して10月6日から正式に動作を開始しました。

皆さんも気づいたかもしれないのですが、そうなんです。このBOTほんとに最近できたばかりなんです。

現在は
**13サーバー**
**330人以上**
の方に使用していただいています。

まだまだ小さなBOTです。今の目標は、100サーバーを超えることです。
最初は友達に宣伝しまくって導入していただいて広げていきました。
このBOTに興味がある方はぜひ自分のサーバーに導入してみてください。

導入リンクは
**・公式のDiscordサーバー**
**・公式ホームページ**
に記載しています。

「不具合なんだけど」や「こんな機能ほしい」という意見も受け付けていますので、お問い合わせください！
さらに開発者の方で興味がある方もぜひご連絡ください。

## 4. まとめ
今回は、みらいサーバーを用いたDiscordBOT作成例から運用の実践例を挙げてみました。
この記事を見て少しでも興味を持っていただけたらと思います。
AdMaxが原因でサイトのローディングが終わらず実害が発生してしまったので削除するしかなかった話

## どんな事象が発生したか

いつ頃からか正確にはわかりませんが、Webサイトのローディングが終わらずChromeのタブのアイコンがず〜とぐるぐるするという事象が発生していました。見た目としては広告の表示も終わっていて動作は問題がないと考えていました。

この事象は少なくとも2024年10月には発生していました。
ネットで検索すると2024年6月に相談の投稿があったりするので、その頃から発生していたのかもしれません。

## 原因は？

忍者AdMaxで広告を表示すると発生します。

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10299302385

ちなみに下記記事で「非同期タグ」にすると解決するという紹介がありますが、私の場合は解決しませんでした。上の投稿でも非表示タグで変わらないと書かれているので望み薄です。

https://www.mayonakanouta.com/blog/javascript-admax

## 実害とは？

ローディングが終わらないだけで広告は表示されていたのでPCブラウザのユーザが少し気になるだけだと軽く考えていました。しかし、これが原因でFirebaseUIでのログイン画面の表示が動作しないという問題があることを発見しました。

https://firebase.google.com/docs/auth/web/firebaseui?hl=ja

AuthUI.startメソッドでログイン画面の描画を開始しますがいつまで経ってもコールバックが帰ってこず描画がされません。諦めてChromeのローディングキャンセルボタン（再読み込みボタンのやつ）を押すとログイン画面が描画されます・・・。

推測ですが、FirebaseUIのAuthUI.stargメソッドのコールバックは画面内の全コンテンツのロードが完了すると呼ばれるようになっているのではないかと思われます。

なのでFirebaseUIに限らずwindow.onloadなどで画面のコンテンツのロードが完了してから実行したい処理があると実害が発生します。

また、なぜか初回画面表示時（キャッシュクリア直後）は正常にローディングが完了します。２回目以降はなにかキャッシュが残っている状況なのかローディングが終わらなくなります。

さらに、localhostでの開発中は発生しないというのも気づくのが遅くなったり、対応策の調査を難しくさせる原因となっています。サーバにデプロイしないと再現確認できないのは、投げ出したくなります。

## 恒久対応

残念ながら致命的な問題だったためすぐに、忍者AdMaxでの広告表示をやめるしかありませんでした。（投げ出しました。）

幸いAdSenseの申請が通っているサイトのためAdSenseだけで広告表示することにしました。

2024年6月からこの状態でこの記事を書いているのが2024年12月であることを考えると問題に気がついていないか治す気がないのではないかと思われます・・・。

どなたか解決方法わかればコメントください！

そこまでしてAdMaxを復活させるかは疑問ですが、AdSenseの申請が通っていないサイトに表示するにはいいサービスだと思うので解決方法には興味があります。

## 開発しているWebサービス（LAR）について

[LAR](https://www.larlar.net/)はアニメファンのためのサイトです。
ログイン不要で自由にアニメのランキングが作成できる「[アニメランキングメーカー](https://www.larlar.net/ranking_maker)」などの機能があります。
[TV](https://www.larlar.net/tv_schedule), [dアニメストア](https://www.larlar.net/d_schedule), [Prime Video](https://www.larlar.net/prime_schedule), [Netflix](https://www.larlar.net/netflix_schedule)のアニメ番組表も公開しています。

- [アニメランキングメーカー](https://www.larlar.net/ranking_maker)
- [おすすめアニメメーカー](https://www.larlar.net/recommend_maker)
- お気に入り表示（ログイン後のみ）
- MY番組表表示（ログイン後のみ）

https://larlar.net/

### アニメランキングアニメメーカー利用例

アニメランキングメーカーを利用すると下記のようなオリジナルランキングが簡単に作成でき、Xに投稿することができます。

- [2024年冬アニメランキング](https://www.larlar.net/ranking/0775cd3f-d47c-41aa-8bd5-07b2ed36609e)

- [好きなアニメランキング](https://www.larlar.net/ranking/ce8cfd82-03b0-4e81-b1d0-5c8f27d2d46a)

- [俺が見たアニメランキング](https://www.larlar.net/ranking/8f4fdb7a-d294-4f67-bc93-95ef249dbb61)

- [見たら人生得する作品10選](https://www.larlar.net/ranking/733748ee-97df-491a-a849-aad766a82a4c)

ぜひ、皆さんもオリジナルランキング作ってみてください！
TCPコネクション

### サーバーはLISTENとACCEPTプリミティブでコネクションの要求を待つ
>三方向ハンドシェイクを使ってコネクションを確立する。コネクション確立のために、サーバーはLISTENとACCEPTプリミティブを使って受動的にコネクション要求を待つ。このとき、特定の送信元を指定することもできる。

### クライアントがCONNECTプリミティブで諸情報を含ませてサーバーに送る
>もう一方の端、つまりクライアントは、CONNECTプリミティブを実行し、接続先のIPアドレスとポート、受信できる最大のTCPセグメント・サイズ（もしあれば)ユーザー・データ（例えばパスワード)を指定する。CONNECTプリミティブはSYNビットをオンにしたTCPセグメントを送り、応答を待つ。

### CONNECTプリミティブが届くと目的のプロセスがlisten状態かを調べる
>このセグメントが宛先に到着すると、宛先のTCPエンティティは宛先ポート・フィールドに指定されたポートでlistenしているプロセスが存在するかを調べる。なければ、RSTビットをオンにした応答を送り、コネクションの確立を拒否する。

### listen状態ならば確認通知を送る
>あるセグメントがそのポートでlistenしている場合、そのプロセスは入力TCPセグメントを受け取り、そのコネクションを受理するか拒否するか決定する。受理する場合、確認通知を送り返す。TCPセグメントの通常のシーケンスを図6−37(a)に示す。SYNセグメントは1バイトの順序番号スペースを用いているので、あいまいなく確認通知されることに注意されたい。

### 二つのソケットで同時にコネクションができる
>二つのホストが同じ二つのソケットの間で同時にコネクションはエンド・ポイントで識別されるので、結果として一つのコネクションだけが確立される。両者とも(x,y)で識別されるコネクションであるから、一つのテーブル・エントリ(x,y)だけが作成される。

### SYNセグメントをたくさん記憶しなきゃいけなくなる攻撃 SYNフラッド
>3方向ハンドシェイク実装の弱点は、リスニング状態のプロセスは、それ`自身のSYNセグメントを返信するとその順序番号を記憶しなければならない`点にある。その性質を使って、悪意のある送信者がSYNセグメントを次から次へと送り、その後何もせずにコネクションを完了させないようにして、ホストのリソースを使い切ることができる。この攻撃は`SYNフラッド(SYN flood）`と呼ばれ、1990年代のWebサーバー攻撃に用いられた。現在では、この攻撃への防御方法はいくつか知られている。

### SYNフラッドを防御するSYNクッキー
>この攻撃に対処する一つの方法は、`SYNクッキー(SYN cookies)`である。ホストは、順序番号を記憶することなく、ある暗号的な関数によって生成された順序番号を選び、SYNセグメントに入れて送り、その番号を忘れる。三方向ハンドシェイクが完了すると、この順序番号+1がホストに返される。この時、ホストは、正しい順序番号を同じ暗号生成関数で再度計算する。ただし、この計算の入力がわかっている限り、正しい結果を得る。この手順によってホストは、順序番号(sequence number)を別々に記憶する必要なしにACK順序番号が正しいことを確認できる。

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/

### 感想
* SYNクッキーの内容は理解できなかった。
* SYNとは？
コマンド一つでQiita記事執筆に取り掛かれるようにする

# やったこと
コマンド一つで記事執筆に取り掛かれるようにしました。
* 作成する記事のプレビュー画面の起動
* エディタの編集画面の起動
```
qiita <作成する記事のタイトル>
```

![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/8a53d5b7-06f1-1b99-2f8d-70e6c8a4d283.gif)

# きっかけ

最近アウトプットができておらず、アウトプットの習慣を作りたいと考えています。
そこでQiitaの記事執筆をラクにする方法を考え、Qiita CLIやGitHubとの連携を行いました。

よりラクにしていく方法を模索し、今回の設定をしました。

# 前提

本記事の設定を行う場合、先に下記2記事の設定を実施する必要があります。

* Qiita CLIの設定

https://qiita.com/Qiita/items/666e190490d0af90a92b

* GitHubの設定

https://qiita.com/Qiita/items/32c79014509987541130

# 設定方法

シェル起動時に読み込まれる設定ファイルに下記を追加します。
私はzshを利用しているので、`~/.zshrc`に追記しました。
`~/git/qiita`の部分は、ご自身のQiitaのリポジトリのルートディレクトリに変更してください。
```
qiita(){
        cd ~/git/qiita
        npx qiita new $1
        code ~/git/qiita/public
        code ~/git/qiita/public/$1.md
        npx qiita preview
}
```

試す場合は`source ~/.zshrc`を実行してください。
シェルを再起動する場合は不要です。

# 感想
* Qiita CLIやGitHubの設定は思っていたより簡単
* 使い慣れたエディタが利用可能で執筆が捗りそう
* 他の記事を参照しやすいのが便利
* 記事の管理が楽になりそう