OmniAICreator/Qiita-1.07M huggingface dataset:
PythonでExcelの行や列を削除する

Excelのスプレッドシートを扱っていると、不要な行や列を削除したくなることがあります。もしプログラムで削除を自動化したいのであれば、**Pythonを使ってExcelの行や列を削除する**以下の3つの方法を参考にしてください：
* [Excelから指定した行や列を削除する](#pythonでexcelの指定した行や列を削除する)
* [Excelから複数の行または列を削除する](#pythonでexcelの複数の行や列を削除する)
* [Excelから空白の行または列を削除する](#pythonでexcelの空白行と空白列を削除する)

## Python Excelライブラリ
上記の方法は、[**Spire.XLS for Python**](https://www.e-iceblue.com/Introduce/xls-for-python.html) ライブラリの助けを借りて実現されているので、まずpipコマンドを使ってライブラリをインストールする必要があります。
> pip install Spire.XLS

## 使用されるクラスとメソッド
インストール後、Excelから行や列を削除するためのSpire.XLS for Pythonライブラリが提供するクラスやメソッドを簡単に見てみましょう：
* **`Workbook`** クラス：ワークブックを表します。
* **`Worksheet`** クラス: ワークシートを表します。
* **`Worksheet.DeleteRow(rowIndex)`** メソッド：指定された行をインデックス単位で削除する（行インデックスは 1 から開始）。
* **`Worksheet.DeleteColumn(columnIndex)`** メソッド：指定された列をインデックス単位で削除する（列インデックスは 1 から開始）。
* **`Worksheet.DeleteRow(startRowIndex, rowCount)`** メソッド： 開始行インデックスと削除する行数を指定して、複数の行を一度に削除します。
* **`Worksheet.DeleteColumn(startColumnIndex、columnCount)`** メソッド： 開始列インデックスと削除する列数を指定して、複数の列を一度に削除する。
* **`Worksheet.Row[rowIndex].IsBlank`** プロパティ： 指定された行が空白行かどうかを判定する。
* **`Worksheet.Column[columnIndex].IsBlank`** プロパティ： 指定された列が空白列かどうかを判定します。


## PythonでExcelの指定した行や列を削除する
 ```python
 from spire.xls import *
from spire.xls.common import *
 
# Workbookオブジェクトの作成
workbook = Workbook()
 
# エクセルファイルを読み込む
workbook.LoadFromFile("input.xlsx")
 
# 最初のワークシートを取得する
sheet = workbook.Worksheets[0]
 
# ワークシートから5行目を削除する
sheet.DeleteRow(5)
 
# ワークシートから3列目を削除する。
sheet.DeleteColumn(3)
 
# 結果ファイルの保存
workbook.SaveToFile("DeleteRowColumn.xlsx", ExcelVersion.Version2016)
workbook.Dispose()
```

## PythonでExcelの複数の行や列を削除する
```python
from spire.xls import *
from spire.xls.common import *
 
# Workbookオブジェクトの作成
workbook = Workbook()
 
# エクセルファイルを読み込む
workbook.LoadFromFile("input.xlsx")
 
# 最初のワークシートを取得する
sheet = workbook.Worksheets[0]
 
# ワークシートから3行目、4行目、5行目、6行目、7行目を削除する（合計5行）
sheet.DeleteRow(3, 5)
 
# ワークシートから4列目と5列目を削除する
sheet.DeleteColumn(4, 2)
 
# 結果ファイルの保存
workbook.SaveToFile("DeleteRowsColumns.xlsx", ExcelVersion.Version2016)
workbook.Dispose()
```

## PythonでExcelの空白行と空白列を削除する
```python
from spire.xls import *
from spire.xls.common import *
 
# Workbookオブジェクトの作成
workbook = Workbook()
 
# エクセルファイルを読み込む
workbook.LoadFromFile("示例.xlsx")
 
# 最初のワークシートを取得する
sheet = workbook.Worksheets[0]
 
# ワークシートから空白行を削除する
for i in range(sheet.Rows.Length - 1, -1, -1):
    if sheet.Rows[i].IsBlank:
        sheet.DeleteRow(i + 1)
 
# ワークシートから空白の列を削除する
for j in range(sheet.Columns.Length - 1, -1, -1):
    if sheet.Columns[j].IsBlank:
        sheet.DeleteColumn(j + 1)
 
# 結果ファイルの保存
workbook.SaveToFile("DeleteBlankRowColumn.xlsx", ExcelVersion.Version2016)
workbook.Dispose()
```

上記の3つの例では、Pythonを使ってExcelの1行や1列を削除する方法、複数の行や列を削除する方法、空白の行や列を削除する方法を示しています。さらに、Spire.XLS for PythonライブラリはExcelファイルの生成、読み込み、編集、変換もサポートしています。その他のデモはこちらをご覧ください。

https://www.e-iceblue.com/Tutorials/Python/Spire.XLS-for-Python/Program-Guide/Spire.XLS-for-Python-Program-Guide-Content.html
PKCEによるOAuth 2.0のセキュリティ強化

## PKCEの概要

PKCEは、OAuth 2.0の拡張仕様として開発された認証セキュリティ強化メカニズムである。

- PKCE: Proof Key for Code Exchange（ピクシーと発音）
- RFC 7636で定義
- 主に認可コード横取り攻撃への対策が目的

## PKCEの仕組み

```mermaid
sequenceDiagram
    participant C as クライアント
    participant AS as 認可サーバー
    
    Note over C: code_verifier生成
    Note over C: code_challengeを生成<br/>(code_verifierをハッシュ化)
    C->>AS: 認可リクエスト + code_challenge
    AS->>C: 認可コード
    C->>AS: トークン要求 + code_verifier
    Note over AS: code_verifierを検証
    AS->>C: アクセストークン
```

1. クライアントが「code_verifier」というランダムな文字列を生成
2. 「code_verifier」をハッシュ化した「code_challenge」を認可リクエスト時に送信
3. アクセストークン取得時に元の「code_verifier」を送信
4. 認可サーバーが「code_verifier」を検証し、正当なクライアントであることを確認

## PKCEの利点

- パブリッククライアント（モバイルアプリやSPA）のセキュリティ向上
- 認可コードの横取りリスクを軽減
- CSRF（クロスサイトリクエストフォージェリ）対策としても有効

## 現在の推奨事項

- 認可コードフローを使用するすべてのクライアントタイプ（ウェブアプリケーションを含む）でPKCEの使用を推奨
- 新規クライアント作成時にPKCEを必須とする設定が一般的

PKCEは、OAuth 2.0のセキュリティを大幅に向上させる重要な拡張機能として、現代のアプリケーション開発において広く採用されている。

## 参考文献

- [A-Frontier - OAuth 2.0セキュリティガイド](https://www.a-frontier.jp/technology/security07/)
- [IBM - OAuth 2.0セキュリティベストプラクティス](https://www.ibm.com/docs/ja/sva/10.0.7?topic=conformance-oauth-20-security-best-current-practice)
- [LINE Developers - PKCEの実装ガイド](https://developers.line.biz/ja/docs/line-login/integrate-pkce/)
自己紹介

初めまして！32歳2児の母、パート兼フリーランスWebコーダーとして活動している　**”うめはる”**　と申します！

大学で情報科学を専攻後、プログラマーとして２年正社員として働きましたが、結婚により退職し、出産・育児・夫の転勤等により10年で7回引っ越し・・・。

プログラマーに戻りたくてもいつまた引っ越しがあるかわからない、子供の帰宅も早いから無理・・・。

**でもプログラミングで仕事がしたい！Webコーダーなら在宅でプログラマーに近い仕事ができるのでは？！**

っという思いでスクールを利用し、半年の学習を得て、案件獲得に至りました！

現在はECサイト運用のパートと業務委託契約２社からお仕事いただいています。

今後はコーダーとしてスキルを磨きつつ、エンジニア路線の学習もしていきます。

どうぞよろしくお願いいたします！
ラズパイ VNC接続 windowsからテキスト貼付けできない。

## ラズパイ3B+と4で発生

解決方法だけ忘れないように書いておく。

貼付けショートカットの確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/e51433c9-6667-ee9f-be08-b3cc3ba5bcef.png)
設定→ショートカット

◎状況確認
①ラズパイの中でコピペができるか。
②win→ラズパイへのコピペができるか。


◎試すこと
マウス中クリックで貼付け
右クリックで貼付け
Ctrl+Shift+V
1文字ずつ貼付け。1文字なら貼り付けれたことがある。次に全文コピペして貼り付けたら全文貼り付けれた。

◎無理なら ①ができるなら・・・
コピペ無しでなんとかラズパイにsambaを設定してメインPCであるwindowsとファイル共有する。
ラズパイのローカルディスクをwindowsのエクスプローラから見えるようにすればOK。

windowsからラズパイにVNC接続する。

下の写真の通り、ラズパイのローカルにテキストファイルを作って、winとラズパイそれぞれからそのテキストファイルを編集（コピペ）する。
ラズパイの中でならコピペできるのでなんとかコピペ成功。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/efc98d38-09dd-2ae2-0676-510bd4700449.png)

## 感想
コピペできないと不便。
VNC側の設定もさくっとgoogle検索してみたけどわからないので、わかるまではこの方法で対処しよう。
APIキー認証の概要と仕組み

## APIキーの概要

APIキーは、ランダムに生成されたアルファベットと数字の文字列で、特定のクライアントやプロジェクトに関連付けられる[^3]。主な目的は以下の通りである：

- プロジェクトの識別
- プロジェクトの承認
- API使用状況の追跡
- 匿名トラフィックのブロック
- API呼び出し回数の制御

## APIキー認証の仕組み

APIキー認証は以下のステップで実行される[^2]：

1. キーの生成: クライアントは、APIプロバイダーからAPIキーを取得または生成する[^2]
2. リクエストへの含有: クライアントは、APIリクエストにキーを含める。これは通常、ヘッダー、クエリ文字列、またはCookieとして送信される[^4]
3. サーバー側の検証: APIサーバーは、受信したキーを許可されたキーのリストと照合する[^3]
4. アクセス制御:
    - キーが一致する場合、サーバーはリクエストを処理し、応答を返す
    - キーが一致しない場合、サーバーはアクセスを拒否し、エラーメッセージを返す[^3]

```mermaid
sequenceDiagram
    participant C as クライアント
    participant A as APIサーバー
    participant B as バックエンドリソース

    C->>A: APIリクエスト + APIキー提示
    Note over A: APIキーの検証
    alt キー有効
        A->>B: リソースアクセス許可
        B-->>C: レスポンス
    else キー無効
        A-->>C: エラーレスポンス
    end
```

## セキュリティ上の考慮事項

APIキーは、一般的に安全とはみなされない[^1]。主な理由は以下の通りである：

- クライアントからアクセス可能
- 盗難の可能性がある
- 有効期限がない場合が多い

より安全な認証方法として、OAuth、トークンベースの認証、またはサービス間認証などが推奨される[^1][^2]。

## APIキーの制限

APIプロバイダーは、APIキーを使用して以下のようなアクセス制限を設定できる[^3]：

- サービスの範囲の制限
- 利用可能な機能の選択
- リクエスト数の制限
- 特定のIPアドレス範囲からのアクセスの制限

これらの制限により、APIの使用を効果的に管理し、不正使用を防ぐことが可能である。

## 参照
[^1] [^2] [^3] [^4] [^5] [^6] [^7] [^8]
[^1]: [https://cloud.google.com/endpoints/docs/openapi/when-why-api-key?hl=ja](https://cloud.google.com/endpoints/docs/openapi/when-why-api-key?hl=ja)
[^2]: [https://apidog.com/jp/blog/introduction-to-api-authentication/](https://apidog.com/jp/blog/introduction-to-api-authentication/)
[^3]: [https://aws.amazon.com/jp/what-is/api-key/](https://aws.amazon.com/jp/what-is/api-key/)
[^4]: [https://www.ibm.com/jp-ja/topics/api-key](https://www.ibm.com/jp-ja/topics/api-key)
[^5]: [https://www.zenrin-datacom.net/solution/blog/api-authentication](https://www.zenrin-datacom.net/solution/blog/api-authentication)
[^6]: [https://financial.ctc-g.co.jp/itinfo/api認証とは？認証が必要な理由や主要な認証方式を解説](https://financial.ctc-g.co.jp/itinfo/api%E8%AA%8D%E8%A8%BC%E3%81%A8%E3%81%AF%EF%BC%9F%E8%AA%8D%E8%A8%BC%E3%81%8C%E5%BF%85%E8%A6%81%E3%81%AA%E7%90%86%E7%94%B1%E3%82%84%E4%B8%BB%E8%A6%81%E3%81%AA%E8%AA%8D%E8%A8%BC%E6%96%B9%E5%BC%8F%E3%82%92%E8%A7%A3%E8%AA%AC)
[^7]: [https://www.gomomento.com/jp/resources/blog-jp/api-keys-vs-tokens-whats-the-difference/](https://www.gomomento.com/jp/resources/blog-jp/api-keys-vs-tokens-whats-the-difference/)
[^8]: [https://zenn.dev/shikumiya_hata/books/33f44d4f561ec4/viewer/fd3203](https://zenn.dev/shikumiya_hata/books/33f44d4f561ec4/viewer/fd3203)
DjangoとVue.jsを連携してデータを渡す方法：HTMLテンプレートを活用した実装

## はじめに

DjangoとVue.jsを組み合わせて使用する際、バックエンドのデータをどのようにフロントエンドに渡すかが重要です。本記事では、Djangoのビューで取得したデータを **（APIViewを使わずに）** HTMLテンプレートを介してVue.jsコンポーネントに渡す具体的な方法について解説します。



## DjangoビューからHTMLへのデータの渡し方

まず、Djangoのビューでデータベースから情報を取得し、それをテンプレートに渡します。この例では、`human_assign_edit`というビューで、ユーザー情報や関連データを取得してコンテキストに格納しています。

```python
def edit_page(request, item_id):
    # データの取得
    item_details = get_item_details(item_id)
    related_data = get_related_data(item_id)

    # 静的データの作成
    months = ["January", "February", "March"]
    categories = [{"id": 1, "name": "Category A"}, {"id": 2, "name": "Category B"}]
    statuses = [{"id": 1, "name": "Active"}, {"id": 2, "name": "Inactive"}]

    # テンプレートに渡すデータ
    context = {
        "itemDetails": item_details,
        "relatedData": related_data,
        "months": months,
        "categories": categories,
        "statuses": statuses,
    }

    # HTMLテンプレートにデータを渡す
    return render(request, "edit_page.html", context)

```

この例では、`get_human_data`や`get_assignment_history`などのカスタム関数でデータを取得・加工し、テンプレートに渡しています。

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓


## HTMLテンプレートからVue.jsへのデータの渡し方

Djangoのテンプレートタグを使用して、コンテキストのデータをJSON形式でVue.jsコンポーネントに渡します。Vue.jsでは、渡されたデータを`props`として受け取ります。

```html
<div id="app">
    <item-editor :item-details="{{ itemDetails|safe }}"
                 :related-data="{{ relatedData|safe }}"
                 :months="{{ months|safe }}"
                 :categories="{{ categories|safe }}"
                 :statuses="{{ statuses|safe }}"></item-editor>
</div>

```

ここで、`{{ ...|safe }}`を使うことで、DjangoテンプレートエンジンがJSONデータを適切にレンダリングし、そのままVue.jsの`props`に渡すことができます。

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

## Vue.jsコンポーネントでのPropsの受け取り方

Vue.jsでは、`props`を使って外部からデータを受け取ります。受け取ったデータは、コンポーネント内で自由に利用できます。

```javascript
export default {
  props: {
    itemDetails: Object,
    relatedData: Array,
    months: Array,
    categories: Array,
    statuses: Array,
  },
};

```

`setup`メソッドを利用することで、受け取ったデータをリアクティブな状態で管理し、コンポーネント内で効率的に扱うことができます。



## まとめ

DjangoとVue.jsを連携させる際、以下の流れでデータを渡します：

1. Djangoビューでデータを取得し、テンプレートにコンテキストとして渡す。
2. HTMLテンプレートでDjangoのテンプレートタグを使い、データをVue.jsコンポーネントに渡す。
3. Vue.jsコンポーネントで`props`として受け取り、活用する。

**補足**:
Django Rest Framework（DRF）を使用してAPIでデータをやり取りする方法も広く採用されていると思います。DRFを利用することで、API経由でデータを直接Vue.jsに渡す方が開発しやすいかも。？
pyaudioのインストールで詰まったときの解決メモ

# 環境
・Ubuntu 24.04.1 LTS
・Python 3.11.9

# エラーログ
```
ERROR: Could not build wheels for pyaudio,,,,
```

# 解決法
```
sudo apt install portaudio19-dev
pip install PyAudio
```

# 参考にした記事
どちらも１年以上前、かつpythonのバージョンも古かったため、本記事記載の環境でも可能か試したが、問題なかった。

大文字小文字は区別されることに注意。

https://qiita.com/musaprg/items/34c4c1e0e9eb8e8cc5a1

https://qiita.com/KobaTaii/items/b7d1107eae0cb52d7ed2


# 追記
MacでもPyAudioがインストールできなかったため追記

## 環境
- MacOS
- Python 3.11.9

## 手順
エラーログは上記と一緒。そこで解決法をMacなのでbrewでinstallしようとすると

```
Warning: No available formula with the name "portaudio19-dev".
```

と出たので、ターミナルの指示通り
```
brew install portaudio
```

を実行した。
その後pipでpyaudioをインストールすると正常にインストールできた！

```
pip install pyaudio
```
応用情報技術者試験受験記 情報セキュリティ編

2024年秋に行われたIPA主催の情報処理試験で、見事応用情報技術者試験に合格しました。
その際、選択した分野別に、資格試験を通して学んだ技術的な内容の記事をこれから投稿していきたいと思います。

選択した分野
・情報セキュリティ　← 今回の記事の内容
・ネットワーク
・データベース
・組込みシステム開発
・情報システム開発

今回は、応用情報技術者試験の分野の一つである、情報セキュリティの勉強を通して、今後の作業に役に立ちそうな技術を簡単に紹介します。
私は主にWeb開発をやっているので、今回は、Webセキュリティについて紹介します。
Webセキュリティを題材とした問題で、頻繁に出てきた単語が、WAF(Web Application Firewall)でした。これはWebアプリケーションに対するアクセスを監視し、不正な操作を遮断するというIT機器です。また、この機器はサニタイジング機能を有しており、SQLインジェクションやクロスサイトスクリプティングなどのような入力フォームに不正なプログラムを入力する攻撃を検知して遮断するという優れものです。もう少し中身について説明していきます。このWAFの検知の材料として使われているものは、シグネチャ（不正な通信、不正な攻撃パターンをまとめた定義ファイル）というものです。シグネチャにはブラックリスト方式とホワイトリスト方式というものがあります。ブラックリスト方式は許してはいけない通信やプログラムを定義します。ホワイトリスト方式はその逆で、許可する通信やプログラムを定義します。一般的におすすめなのはホワイトリスト方式です。ブラックリスト方式は、許可したくない通信が増えるたびに更新しなくてはいけませんが、ホワイトリスト方式は、定義した通信やプログラム以外は全て遮断してくれるので、運用上セキュリティ管理が容易で安全性が高いのはホワイトリスト方式の方です。

まとめ
年々サイバー攻撃の件数は増加の一途をたどっています。そんな中、セキュリティを生業としたエンジニアになれればとてもかっこいいと思いました。応用情報技術者試験では、自分や会社を守る術を覚えましたが、次は、情報処理安全確保支援士試験に挑戦して、セキュリティを生業として仕事をできる人材になりたいと思います。
HTTP Basic Authenticationの概要と仕組み

## 1. 基本概念

HTTP Basic Authenticationは、HTTPプロトコルに組み込まれた最も基本的な認証方式の一つである[^1]。ユーザー名とパスワードによってクライアントの身元を確認する認証の仕組みであり、認可の機能は含まれない。

## 2. 主な特徴

- シンプルで実装が容易な認証方式[^2]
- ほとんどのWebブラウザやHTTPクライアントで標準サポート[^2]
- ステートレスな認証方式（アクセスごとの認証情報送信）[^2]
- ディレクトリごとのアクセス制限設定が可能[^3]

## 3. 認証フロー

### 初回アクセス時

1. クライアントによる保護リソースへのアクセス[^1]
2. サーバーからの「401 Unauthorized」と「WWW-Authenticate」ヘッダー返信[^1]
3. ブラウザによる認証情報入力要求[^2]
4. 認証情報の処理：
    - ユーザー名とパスワードの「:」による結合[^1]
    - 結合文字列のBase64エンコード[^1] [^7]
    - 「Authorization: Basic」ヘッダーへの追加[^1]
5. サーバーによる認証検証とアクセス制御[^1]

### 認証済みの場合

1. クライアントによる保護リソースへのアクセス（Authorization: Basicヘッダー付き）
2. サーバーによる認証情報の検証
3. リソースへのアクセス許可

```mermaid
sequenceDiagram
    participant C as クライアント
    participant S as サーバー

    %% 初回アクセス時
    C->>S: 保護されたリソースへアクセス
    S-->>C: 401 Unauthorized + WWW-Authenticate
    Note over C: ブラウザによる認証情報入力要求
    C->>C: ユーザー名とパスワードの結合 (: で結合)
    C->>C: Base64エンコード
    C->>C: Authorization: Basic [エンコード文字列] ヘッダーに追加
    C->>S: Authorization: Basic [エンコード文字列]
    Note over S: 認証情報を検証とアクセス制御
    alt 認証成功
        S-->>C: 200 OK + リソース
    else 認証失敗
        S-->>C: 401 Unauthorized
        Note over C: ブラウザによる認証情報入力要求
    end

    %% 認証済みの場合
    C->>S: 保護されたリソースへアクセス (Authorization: Basic ヘッダー付き)
    Note over S: 認証情報の検証
    alt 認証成功
        S-->>C: 200 OK + リソース
    else 認証失敗
        S-->>C: 401 Unauthorized
        Note over C: ブラウザによる認証情報入力要求
    end
```

## 4. 実装例

認証情報の例（ユーザー名: user、パスワード: pass）：

```jsx
# 元の文字列
user:pass

# Base64エンコード後
dXNlcjpwYXNz

# HTTPリクエストヘッダー
Authorization: Basic dXNlcjpwYXNz
```

## 5. セキュリティ上の考慮点

- 認証情報は単なるBase64エンコードであり、暗号化なし[^2] [^7]
- HTTPS未使用時の通信途中での盗聴リスク[^3]
- ブルートフォース攻撃への脆弱性[^3]
- 重要データの保護には不適[^3]
- HTTPS（SSL暗号化）との併用が必須[^3] [^8]

## 6. 推奨される使用場面

- 開発環境やテスト環境での一時的認証[^3]
- 内部ネットワークでの簡易的アクセス制御[^3]
- HTTPS確実使用環境での基本認証[^3]
- 高度な認証方式実装前の暫定措置[^3]

---

参照
[^1] [^2] [^3] [^4] [^5] [^6] [^7] [^8]
[^1]: [https://www.keepersecurity.com/blog/ja/2024/03/08/what-is-basic-access-authentication/](https://www.keepersecurity.com/blog/ja/2024/03/08/what-is-basic-access-authentication/)
[^2]: [https://www.aeyescan.jp/blog/basic-authentication/](https://www.aeyescan.jp/blog/basic-authentication/)
[^3]: [https://www.shadan-kun.com/blog/measure/461/](https://www.shadan-kun.com/blog/measure/461/)
[^4]: [https://www.winserver.ne.jp/column/about_basic-authentication/](https://www.winserver.ne.jp/column/about_basic-authentication/)
[^5]: [https://qiita.com/ooo-lang/items/f067c34146f889179652](https://qiita.com/ooo-lang/items/f067c34146f889179652)
[^6]: [https://zenn.dev/mukkun69n/articles/e697d5b9589345](https://zenn.dev/mukkun69n/articles/e697d5b9589345)
[^7]: [https://qiita.com/SHOT0/items/878648bf619f775c9928](https://qiita.com/SHOT0/items/878648bf619f775c9928)
[^8]: [https://qiita.com/SHOT0/items/cae08a65be065ba07acd](https://qiita.com/SHOT0/items/cae08a65be065ba07acd)
ビルドされたVue.jsではタグ内でのインスタンス初期化実行がエラーになる

## 先に結論
Vueのテンプレートタグ内で以下のようなインスタンスの初期化をしてはいけません。
```vuejs
<template>
  <div v-for="booking in allBookingsByCategory(categoryId)" :key="`${booking.id}`">
    <div class="patient-name">
      <!-- 下記がNG -->
      {{ new PatientNameService(booking).fullName }}
    </div>
  </div>
</template>
```

## 発生したエラーの詳細
本番環境にて`Class constructor XXX cannot be invoked without 'new'`というエラーが発生しました。

[![Image from Gyazo](https://i.gyazo.com/b79999c4a2dfc6caefb904ce2cdaa961.png)](https://gyazo.com/b79999c4a2dfc6caefb904ce2cdaa961)

## 原因
`<template>`タグ内でインスタンスの初期化を行っている部分にて、エラーが発生していました。
冒頭にも挙げた下記のようなコードです。

```vuejs
<template>
  <div v-for="booking in allBookingsByCategory(categoryId)" :key="`${booking.id}`">
    <div class="patient-name">
      <!-- 下記がNG -->
      {{ new PatientNameService(booking).fullName }}
    </div>
  </div>
</template>
<script setup lang="ts">
/**
 * 該当カテゴリから予約一覧を取得
 * @param categoryId 
 */
const allBookingsByCategory = (categoryId: string) => {
  const slotCategory = props.categories[categoryId]
  if (!slotCategory) return []

  return slotCategory.bookings
}
</script>
```

## 対応
`<template>`タグ内でインスタンスの初期化を行わないようにして、`<script>`タグ内でインスタンスの初期化を行い、プロパティとして追加するようにしました。

```vuejs
<template>
  <div v-for="booking in allBookingsByCategory(categoryId)" :key="`${booking.id}`">
    <div class="patient-name">
      <!-- 単純にプロパティにアクセスするように修正 -->
      {{ booking.patientFullName }}
    </div>
  </div>
</template>
<script setup lang="ts">
/**
 * 該当カテゴリから予約一覧を取得
 * @param categoryId 
 */
const allBookingsByCategory = (categoryId: string) => {
  const slotCategory = props.categories[categoryId]
  if (!slotCategory) return []

  // ここで patientFullName を取得してプロパティとして追加する
  return slotCategory.bookings.map((booking) => {
    const patientFullName = new PatientNameService(booking).fullName
    return { ...booking, patientFullName }
  })
}
</script>
```


## 厄介だったこと
:::note alert
この問題は**開発環境では発生しません**⚠️
:::
コンパイルされた成果物にてのみ発生します。
開発環境でうまく動いたのでと安心していると、いざビルドした成果物をデプロイした本番環境にて動かない、ということにもなり得るので注意が必要です。
明確な発生のメカニズムは分かっていませんが、ビルド時にminifyが走って`<template>`タグ内でクラス名を見つけられない、というようなことが起きているのではと推測しています。


## 参照

https://stackoverflow.com/questions/74069642/class-constructor-cannot-be-invoked-without-new-instantiating-own-class-i

https://github.com/vuejs/core/issues/6483
DB設計の基本カラム：作成日時から削除フラグ

https://kamatimaru.hatenablog.com/entry/2020/10/25/064448

## DB作成時に必須となるカラム

データベースの設計時、特に以下の3つのカラムを追加するのはほぼ必須と言えます。

- **作成日時 (`created_at`)**: データが作成された日時を記録します。
- **更新日時 (`updated_at`)**: データが最後に更新された日時を記録します。
- **削除日時 (`deleted_at`)**: データが削除された日時を記録します（論理削除の場合に利用）。

これらのカラムを設けることで、データの履歴を追跡しやすくなり、システムの保守性が向上します。



## システムの要件によっては追加するカラム

プロジェクトの要件によっては、以下のカラムも追加を検討してください：

- **作成者 (`created_by`)**: データを作成したユーザーやプロセスの識別子を記録します。
- **更新者 (`updated_by`)**: データを最後に更新したユーザーやプロセスの識別子を記録します。

これらを導入することで、データの作成・更新履歴を詳細に管理できます。大規模なシステムでなければ困ったら導入するのもありだと思います。


### 実装例
以下はDjangoモデルを用いた具体例です：
```
class HumanCapitals(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=30, unique=True)
    position = models.ForeignKey(Positions, on_delete=models.SET_NULL, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    deleted_at = models.DateTimeField(blank=True, null=True)
```
この例では、created_atやupdated_atをDjangoが内部的に特定のタイミングで値を自動的に設定するようになります。




## データが削除されるのであれば `deleted_at` カラムは必要か？

新人時代の私の疑問を解消してくれる、こちらの記事から引用します。

https://zenn.dev/kotahashihama/articles/f9676a52bd83c9

> データが削除されると `deleted_at` カラムを含むデータごと消えるので、その必要性に疑問を持つかもしれません。しかし、`deleted_at` カラムが有効な場合もあります。データベース設計には「物理削除」と「論理削除」という二つのレコード削除方式があります。
> 
> ### 物理削除
> 物理削除は、レコードをデータベース上から完全に消し去る方法です。この方法では、基本的にデータの復元はできません。
> 
> ### 論理削除
> 論理削除では、「削除」と言いますが、実際にはレコードを削除しません。`deleted_at` などのカラム（削除フラグ）をテーブルに用意し、その値によって「これは削除されているレコードだ」と見なす概念的な削除です。
> 
> #### メリット
> - 例えば、特定の店舗データが一時的に不要になった場合、アプリケーションからは消去することができますが、将来的にそのデータの復元が必要になる可能性があります。
> - 間違ってデータを消去した場合、簡単に復元することができます。
> 
> #### デメリット
> - データが残り続けるため、データベースの容量を圧迫してしまうことがあります。
> 

## まとめ

データベース設計では、`created_at`、`updated_at`、`deleted_at`といったカラムを設置することで、データの管理が格段にしやすくなります。システムの要件に応じて、`created_by`や`updated_by`などの追加カラムも検討してください。
Git Sync・Pull Request自動コメント機能についての感想

# はじめに

2023年のRe:inventにて登場したGit sync。CloudFormationとGit間で、スムーズな接続ができる魅力的な機能です。2024年9月に、Pull Requestに自動でコメントする機能が追加されたので、実際に使ってみた結果を記事にしてみたいと思います。

↓ Git Syncでコメント機能追加のアナウンス

https://aws.amazon.com/jp/about-aws/whats-new/2024/09/aws-cloudformation-git-sync-supports-pull-request-workflows/

↓ 使い方マニュアル

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/gitsync-enable-comments-on-pull-requests.html


## Git Syncとは
GitHub、GitHub Enterprise、GitLab、BitbucketからCloudFormationに接続できる仕組み。

> テンプレートまたはデプロイファイルへの変更をコミットすると、CloudFormation はスタックを自動的に更新します。これにより、プルリクエストとバージョントラッキングを使用して、一元化された場所から CloudFormation スタックの設定、デプロイ、更新を行うことができます。


https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/git-sync.html

## Git Syncのコメント機能の使い方
Git Syncの設定から、`Enable comment on pull request`を有効にすると使えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851817/a3c5a491-de9d-82e6-3921-2aa2d8f105b3.png)

設定すると、変更の有無に関わらず、Pull requestに自動でコメントが追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851817/46e34a39-a752-f8c8-0349-01cc2f48d785.png)

修正内容があった場合の通知内容は以下のようになるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851817/7a5c8c62-5a3c-bb9e-c804-f45262978607.png)
（引用：[[アップデート] AWS CloudFormation の Git 同期機能がプルリクエストにスタック変更内容をコメントしてくれるようになりました](https://dev.classmethod.jp/articles/cfn-git-sync-supports-pull-request-workflows/)）

## 実際に使ってみて

自動でコメントがついてくれるのはありがたいと思いました。
ただ、今回作成したGit Syncは、以下のようなものでした。
- Git Syncが設定されているCfnスタック以外のコードも含まれているGitHubリポジトリで作成
- Git Syncはmasterブランチで設定

そのため、Git Syncとは関係ないコードを修正したmasterブランチのPull Requestにも、コミットの度に、「変更点はありません」というようなコメントが付いてしまいました。それを受けて、自動コメント機能はOFFに設定しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851817/1463cbd7-6beb-5ede-4bbb-6d8dde99b2b1.png)

今回の経験から、自動コメント機能が適しているケースとそうでないケースについて考えてみました。

- 自動コメント機能が適しているケース
  - Git Syncを設定したCfnスタックのみのGitリポジトリ
  - 使用頻度の低いブランチでGit Syncを設定している
- 自動コメント機能が適していないケース
    - Git Syncを設定したCfnスタック以外にも様々なコードが含まれているGitリポジトリ
    - main・masterブランチ等、多くの開発者が頻繁にPull Requestを出すブランチでGit Syncを設定している

自動コメント機能は便利な一方で、ノイズにもなりやすいと分かったので、ケースによって使い分けていきたいと思いました。


以上です。ありがとうございました。
自作のSlackアプリの自作のスラッシュコマンドのPOSTリクエストのヘッダの内容を確認する

## 概要

自作のSlackアプリの自作のスラッシュコマンドから送られるPOSTリクエストのヘッダの内容を確認する方法を簡単にまとめる。

## 前提

- 管理者権限を持っているSlackワークスペースがあること
- 自作のSlackアプリがあり、下記の条件を満たした設定になっていること
    - 自作のスラッシュコマンド`/lambda_trigger`が設定されていること
    - スコープが「chat:write」のBot User OAuth Tokenがあること
    - 自作のSlackアプリが任意のSlackワークスペースのgeneralチャンネルに入っていること
    - generalチャンネルのチャンネルIDを知っていること
- ローカルPCでserverless frameworkが動く状態になっていること

※筆者は参考文献先を参考に対応済み

## 方法

1. 下記の内容を参考にserverlessのプロジェクトを新規作成
    - [https://qiita.com/miriwo/items/75a04240de0134c29312](https://qiita.com/miriwo/items/75a04240de0134c29312)

1. serverlessのhandler.jsを下記の様に記載

    ```handler.js
    exports.hello = async (event) => {
      console.log("Headers:", event.headers);
      console.log("Body:", event.body);
      return {
        statusCode: 200,
        body: JSON.stringify({
          message: "処理終わり〜",
        }),
      };
    };
    ```

1. serverless.ymlのhttpApiのmethodがpostになっていることを確認し`$ serverless deploy`を実行
1. 表示されたエンドポイントURLをコピー
1. [https://api.slack.com/apps](https://api.slack.com/apps)にアクセスし、サイドバーの「Slash Commands」で`/lambda_trigger`コマンドのリクエスト送信URLに「表示されたエンドポイントURLをコピー」を貼り付け
1. Slackのgeneralチャンネルで`/lambda_trigger`を実行
1. 当該のAWSにブラウザでログインし、当該のlambda関数のログを確認
1. 下記の様にヘッダ情報がでていたら完了

    ![CleanShot 2025-01-17 at 14.16.07@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/3dfe1013-f662-66fd-d78f-acd0a816fd5e.png)


## 参考文献

https://qiita.com/akis1215/items/cb68b2de6542a742da0a

https://qiita.com/80syokumotsu/items/041e99e99d8ecaa3c42b

https://reigle.info/entry/2022/10/23/100000

https://qiita.com/miriwo/items/75a04240de0134c29312
Proxymanを使って Android12以降でL2TP/IPsecのVPNに接続

Android12以降、L2TP/IPSecプロファイルの新規作成ができなくなって、IKEv2/IPSecのみになりました。しかし、L2TP/IPSecのVPNにアクセスする必要があったのですが、Androidから直接接続できないので、あれこれ試した結果、ProxymanをつかったMac/PCで接続したVPNを経由することでアクセスすることができたので、簡単に記したいと思います。

## 問題
- Android 12以降のデバイスからL2TP/IPSecで直接VPN接続できない
- VPNサーバーがL2TP/IPSecしかサポートしておらず、別のプロトコルに変更できない
- MacのWifiでVPN接続し、それをインターネット共有でAndroidデバイスを接続させようとしたが、VPN接続中にインターネット共有を有効にすると、VPN接続が切断されてしまう
- Android11でL2TP/IPSecのVPNに接続し、それをテザリングでAndroid12以降のデバイスに共有したが、Android12以降のデバイスではVPNにアクセスできない
  - Android11のデバイスはVPNのIPアドレスになっているが、Android12以降のデバイスではインターネットにはつながっているが、VPNを接続をしていない元々のネットワークのIPアドレスになってしまう

## 解決策：Proxymanを利用する
Proxymanは、HTTP/HTTPS通信をキャプチャ、デバッグ、書き換えできる強力なネットワークツールです。

https://proxyman.io/

[Capture HTTP(s) traffic from Android Device](https://proxyman.io/android-device) では証明書のインストールなどが記載されていますが、今回はパケットのキャプチャが不要だったので、MacでProxymanを立ち上げたあと、AndroidのデバイスでProxy設定としてMacのローカルIP(192.168.x.x)とポート番号(9090)を設定するだけでした。
Salesforce Commerce Cloud OCAPIをcurlで試す

# やること
在庫取得

# 必要な情報
接続用のクライアントIDとシークレット - アカウントマネージャから作る？今回は与えられた状態から開始とする
接続先ドメイン
在庫リストID
商品ID

# OCAPI設定
管理 >  サイトの開発 >  Open Commerce API 設定
タイプの選択：データ
範囲の選択：グローバル (組織全体)
```
{
  "_v": "23.2", ← 呼び出し時のバージョンと違っていてもOK
  "clients":
  [
    {
      "client_id": "＜クライアントID＞",
      "resources":
      [
        ～ 中略 ～
        { 
          "resource_id": "/inventory_lists/*/product_inventory_records/*", 
          "methods": ["get"], 
          "read_attributes": "(**)", 
          "write_attributes": "(**)"
        }
      ]
    }
  ]
}
```

# アクセストークン取得

## curlコマンド
```
curl --trace-ascii - --ssl-no-revoke https://account.demandware.com/dwsso/oauth2/access_token?grant_type=client_credentials --data-urlencode "client_id=＜クライアントID＞" --data-urlencode "client_secret=＜クライアントシークレット＞"
```

## 正常実行結果(抜粋)
```
POST /dwsso/oauth2/access_token?grant_type=client_credentials HTTP/1.1
Host: account.demandware.com
Content-Type: application/x-www-form-urlencoded

client_id=＜クライアントID＞&client_secret=＜クライアントシークレット＞
```
```
HTTP/1.1 200 OK
content-type: application/json;charset=UTF-8

{"access_token":"＜アクセストークン＞",～略～}
```

# 在庫取得

## curlコマンド
```
curl -v --ssl-no-revoke https://＜接続先ドメイン＞/s/-/dw/data/v23_2/inventory_lists/＜在庫リストID＞/product_inventory_records/＜商品ID＞ --header "Authorization: Bearer ＜アクセストークン＞"
```

## 正常実行結果(抜粋)
```
GET /s/-/dw/data/v23_2/inventory_lists/＜在庫リストID＞/product_inventory_records/＜商品ID＞ HTTP/1.1
Host: ＜接続先ドメイン＞
Authorization: Bearer ＜アクセストークン＞
```
```
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{"_v":"23.2","_type":"product_inventory_record","_resource_state":"～略～","allocation":{"_type":"product_inventory_record_allocation","amount":10,"reset_date":"2024-12-26T09:47:01.802Z"},"ats":10,"creation_date":"2024-05-31T02:00:03.000Z","inventory_list_id":"＜在庫リストID＞","inventory_turnover":0,"last_modified":"2024-12-26T09:47:01.000Z","link":"～略～","perpetual_flag":false,"pre_order_back_order_handling":"none","product_id":"＜商品ID＞","product_name":"～略(商品名)～","quantity_on_order":0,"stock_level":10}
```

## 異常実行結果(抜粋)

### アクセストークン不正(例えば期限切れ等)
```
HTTP/1.1 401

{"_v":"23.2","fault":{"arguments":{"accessToken":"＜アクセストークン＞"},"type":"InvalidAccessTokenException","message":"Unauthorized request! The access token '＜アクセストークン＞' is invalid."}}
```

### OCAPI設定不足(例えばmethodsにgetが不足している等)
```
HTTP/1.1 403 Forbidden

{"_v":"23.2","fault":{"arguments":{"method":"GET","path":"～略～"},"type":"ClientAccessForbiddenException","message":"Access to resource 'GET /data/v23_2/inventory_lists/＜在庫ID＞/product_inventory_records/＜商品ID＞' isn't allowed for the current client."}}
```
 OCAPI設定を修正後にトークン取得からやり直し
【MYSQL】日本語が文字化けになった時の対策

**問題**
保存される日本語データはDB上で`文字化け`になった問題が起こった。

**解決策**
まずデータベースやテーブルがUTF-8対応できるかどうかを見る。
```sql
SHOW VARIABLES LIKE 'character_set%';
```
`character_set_server や character_set_database が utf8mb4 になっているか確認する。
```sql
+--------------------------+--------------------+
| Variable_name            | Value              |
+--------------------------+--------------------+
| character_set_client     | utf8mb4           |
| character_set_connection | utf8mb4           |
| character_set_database   | utf8mb4           |
| character_set_filesystem | binary            |
| character_set_results    | utf8mb4           |
| character_set_server     | utf8mb4           |
| character_set_system     | utf8              |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+--------------------+

```
`character_set_server` および `character_set_database` が `utf8mb4` になっていることを確認する。
他の値（例: `latin1`）が設定されている場合、文字化けの原因となることがある。もし`latin1`だと、下記のようにデータベースの文字セットを変える。
```sql
ALTER DATABASE `your_database_name` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
```
データベースではなく、テーブルの文字セットを変えたい場合は、下記のように変える。
```sql
ALTER TABLE `your_table_name` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
```
最後に、変更が反映されているかを確認する。
```sql
SHOW VARIABLES LIKE 'character_set%';
```
HTTPSの概要と仕組み

## 1. HTTPSとは

HTTPSとは、HTTPにTLS（Transport Layer Security）による暗号化を追加したプロトコルである。Webブラウザとサーバー間の通信を安全に保護する仕組み。[^1] [^3]

## 2. 主な特徴と利点

- データの機密性、完全性、認証の確保
- 通信の暗号化によるデータ保護[^1] [^3]
- サーバーの身元確認（SSL/TLS証明書による認証）[^1][^3]
- データの改ざん防止[^1]
- コンテンツ注入の防止[^3]

## 3. SSL/TLS暗号化の仕組み

HTTPSはSSL/TLSを使用して通信を暗号化する。暗号化された通信内容は、第三者が傍受しても解読不能な形式となる。[^3]

## 4. 通信の流れ（TLSハンドシェイク）

1. クライアントが対応可能な暗号化方式をサーバーに送信
2. サーバーが使用する暗号化方式を選択して返信
3. サーバーが証明書を送信
4. クライアントが証明書を検証
5. クライアントが鍵交換情報を送信
6. サーバーが完了通知を送信
7. 暗号化通信の開始[^2]

```mermaid
sequenceDiagram
    participant C as クライアント
    participant S as サーバー

    C->>S: クライアントHello（対応可能な暗号化方式）
    S->>C: サーバーHello（選択された暗号化方式）
    S->>C: 証明書送信
    C->>C: 証明書の検証
    C->>S: クライアント鍵交換
    S->>C: サーバー完了
    Note over C,S: 暗号化通信開始
```

## 5. 具体的な通信ステップ

1. クライアントからサーバーへのリクエスト送信
2. サーバーからのサーバー証明書と公開鍵送信
3. クライアントによるサーバー証明書確認、公開鍵での共通鍵暗号化
4. 暗号化された共通鍵のサーバーへの送信
5. サーバーによる秘密鍵での共通鍵復号
6. 共通鍵による暗号化通信開始[^2]

```mermaid
sequenceDiagram
    participant C as クライアント
    participant S as サーバー
    
    C->>S: リクエスト送信
    S->>C: 証明書・公開鍵送信
    Note over C: 証明書確認
    Note over C: 共通鍵生成・暗号化
    C->>S: 暗号化された共通鍵送信
    Note over S: 秘密鍵で共通鍵を復号
    Note over C,S: 共通鍵による暗号化通信開始
```

## 6. セキュリティ機能

- **データの暗号化：** 通信内容の盗聴防止[^1][^3]
- **改ざん防止：** メッセージ認証コード(MAC)によるデータの完全性保証[^1]
- **サーバー認証：** SSL/TLS証明書による正規サーバーの確認[^1][^3]

HTTPSは特に、ログイン情報や個人情報、支払い情報などの機密データを扱う場面で重要な役割を果たす。現代のWebブラウザはHTTPSを重視しており、HTTPSを使用していないサイトは「安全でない」との表示がされることがある[^3]。

---

参照
[^1] [^2] [^3] [^4] [^5]
[^1]: [https://qiita.com/nucomiya/items/f4251cfd3e2ff8fd2612](https://qiita.com/nucomiya/items/f4251cfd3e2ff8fd2612)
[^2]: [https://www.gmo.jp/security/ciphersecurity/http-https/blog/https-protocol/](https://www.gmo.jp/security/ciphersecurity/http-https/blog/https-protocol/)
[^3]: [https://www.cloudflare.com/ja-jp/learning/ssl/what-is-https/](https://www.cloudflare.com/ja-jp/learning/ssl/what-is-https/)
[^4]: [https://www.gmo.jp/security/ciphersecurity/http-https/blog/what-is-https/](https://www.gmo.jp/security/ciphersecurity/http-https/blog/what-is-https/)
[^5]: [https://qiita.com/Threen/items/f799303a76b505f357e2](https://qiita.com/Threen/items/f799303a76b505f357e2)
Base64の概要と仕組み

# Base64とは

Base64は、バイナリデータをテキスト形式に変換するための効率的な仕組みである。

## 1. 基本的な特徴

- 6ビット単位でのデータ処理
- 64種類の文字セットを使用（A-Z, a-z, 0-9, +, /）
- ASCII文字の範囲内で安全な処理が可能

## 2. 文字セットの構成

- 英大文字（A-Z）: 26文字
- 英小文字（a-z）: 26文字
- 数字（0-9）: 10文字
- 記号（+ と /）: 2文字
- パディング文字（=）: 補完用

### Base64変換対応表

| **バイナリ** | **文字** | **バイナリ** | **文字** | **バイナリ** | **文字** | **バイナリ** | **文字** |
| ------------ | -------- | ------------ | -------- | ------------ | -------- | ------------ | -------- |
| 000000       | A        | 010000       | Q        | 100000       | g        | 110000       | w        |
| 000001       | B        | 010001       | R        | 100001       | h        | 110001       | x        |
| 000010       | C        | 010010       | S        | 100010       | i        | 110010       | y        |
| 000011       | D        | 010011       | T        | 100011       | j        | 110011       | z        |
| 000100       | E        | 010100       | U        | 100100       | k        | 110100       | 0        |
| 000101       | F        | 010101       | V        | 100101       | l        | 110101       | 1        |
| 000110       | G        | 010110       | W        | 100110       | m        | 110110       | 2        |
| 000111       | H        | 010111       | X        | 100111       | n        | 110111       | 3        |
| 001000       | I        | 011000       | Y        | 101000       | o        | 111000       | 4        |
| 001001       | J        | 011001       | Z        | 101001       | p        | 111001       | 5        |
| 001010       | K        | 011010       | a        | 101010       | q        | 111010       | 6        |
| 001011       | L        | 011011       | b        | 101011       | r        | 111011       | 7        |
| 001100       | M        | 011100       | c        | 101100       | s        | 111100       | 8        |
| 001101       | N        | 011101       | d        | 101101       | t        | 111101       | 9        |
| 001110       | O        | 011110       | e        | 101110       | u        | 111110       | +        |
| 001111       | P        | 011111       | f        | 101111       | v        | 111111       | /        |

## 3. 変換プロセス

Base64変換の基本プロセス：

1. 入力データのバイト列への変換
2. バイト列の2進数（8ビット）表現への変換
3. 2進数データの6ビット単位への分割
4. パディング処理（必要な場合）
5. 6ビット値のBase64文字へのマッピング
6. パディング文字（=）の追加（必要な場合）

具体例："Logto"の変換プロセス

```mermaid
graph TD;
A["入力テキスト: 'Logto'"] --> B["ASCIIコード変換:<br> L (76), o (111), g (103), t (116), o (111)"]
B --> C["バイナリ変換:<br>01001100 01101111 01100111 01110100 01101111"]
C --> D["6ビット単位の分割:<br>010011 000110 111101 100111 011101 000110 1111"]
D --> E["パディング処理（ビット追加）:<br>010011 000110 111101 100111 011101 000110 111100"]
E --> F["10進数変換:<br>19, 6, 61, 39, 29, 6, 60"]
F --> G["Base64文字へのマッピング:<br>T, G, 9, n, d, G, 8"]
G --> H["最終結果: 'TG9ndG8='"]
```

## 4. データ変換の効率性

- データ量増加の抑制
    - 3バイトのデータを4文字に変換する仕組みによる約33%の増加率
    - 例：「abc」（3文字）→「YWJj」（4文字）
- 他方式との効率性比較
    - 16進数変換ではデータ量が2倍（100%増加）となる
        - 例：「abc」（3文字）→「616263」（6文字）
    - 6ビット単位の変換による増加率の抑制

## 5. 主な用途

- 電子メール（MIME）添付ファイル
- JSON/XMLのバイナリデータ埋め込み
- URLパラメータでのデータ転送
- JWT（JSON Web Token）

## 6. 利点

- 全環境での安全な利用
- 制御文字の排除
- 印刷可能文字のみの使用
- 各種プロトコルとの高い互換性
stripeの特徴とメリット(クレジットカード決済機能をつけるか迷っている方向け)


**個人開発中のアプリを作る時にクレジットカード決済機能をつけるかどうか検討したの簡単にセキュリティ面も考慮できるstripeについて書こうと思います。**


# Stripeのメリットを、より分かりやすくまとめてみました。

## 1. 安全なカード情報管理
  - 安全な環境での保存: ユーザーのクレジットカード情報を、Stripeが提供する高度なセキュリティシステムで保護された環境に保管できます。

  - セキュリティ要件のクリア: 業界標準のセキュリティ基準を満たしているため、安心して決済処理を行うことができます。
## 2. 柔軟な決済機能の組み込み
   - API連携: StripeのAPIを利用することで、自社のサービスに決済機能をスムーズに組み込むことができます。
   - カスタマイズ性: 多様な決済方法に対応しており、自社のビジネスモデルに合わせて柔軟にカスタマイズできます。
## 3. わかりやすい料金体系
   - 完全従量課金: 利用した分だけ料金が発生するため、無駄なコストを抑えられます。
   - 低コスト: 決済手数料が3.6%と比較的安価であり、コストパフォーマンスが高いです。
## まとめ

Stripeは、高いセキュリティ、柔軟な機能、わかりやすい料金体系という3つの大きなメリットを備えた決済サービスです。これにより、様々な規模の企業が手軽にオンライン決済システムを導入できるようになっています。


https://stripe.com/jp?utm_campaign=APAC_JP_JA_Search_Brand_Payments-Pure_EXA-21278920274&utm_medium=cpc&utm_source=google&ad_content=699150004484&utm_term=stripe&utm_matchtype=e&utm_adposition=&utm_device=c&gad_source=1&gclid=Cj0KCQiA-aK8BhCDARIsAL_-H9k8FS5Tbg68vSihbKBZTvwKqlPADWjEZNM15oUIqbnTCy0OQfSRdgQaApYGEALw_wcB
MACのローカルでserverlessをセットアップしてデプロイするところまでのメモ

## 概要

MACのローカルでserverlessフレームワークをセットアップしてAWSにデプロイするまでのメモをまとめる。

## 前提

今回のServerless FrameworkはNode.js 20.Xでlambda関数を作成する。

MacのローカルにはNode.jsが入っており、そのNode.jsはvoltaにより管理されている。
下記コマンドを実行して、command not foundにならないこと。またNode.jsのバージョンが20.Xになっていること。

```sh
npm -v
node -v
volta -v
```

MacのローカルにはAWS CLIがはいっており、下記コマンドを実行して、command not foundにならないこと。

```sh
aws -h
```

AWSのアカウントを保持しており、下記を実行した結果がそのアカウント情報と一致していること（アクセスキーとシークレットキーはAWSのマネジメントコンソールログイン後、IAMに移動し、当該ユーザーの詳細に移動し、「アクセスキー」の部分で確認する事ができる。シークレットキーはあとから確認できないため、わからなかったら「アクセスキー」を作り直してしまう方が早い。作り直すときは「AWSの外部のサービスから使用・・・」的なものを選んでアクセスキーを作成する）

```sh
aws configure
```

`$ serverless -h`コマンドがnot foundにならないこと。

## 方法

1. 任意のディレクトリで｀＄ serverless｀コマンドを実行
1. 下記の様に出るので`AWS / Node.js / HTTP API`を選択してEnter

    ```sh
    ? Select A Template: … 
    ❯ AWS / Node.js / HTTP API
      AWS / Node.js / Express API
      AWS / Node.js / Express API with DynamoDB
      AWS / Node.js / Scheduled Task
      AWS / Node.js / Simple Function
      AWS / Python / HTTP API
      AWS / Python / Flask API
      AWS / Python / Flask API with DynamoDB
      AWS / Python / Scheduled Task
      AWS / Python / Simple Function
      AWS / Compose / Serverless + Cloudformation + SAM
    ```

1. 「? Name Your Project:」と聞かれたら、任意のプロジェクト名を入力してEnter
1. 下記の様に出るので`Create A New App`を選択してEnter

    ```sh
    ? Create Or Select An Existing App: … 
    ❯ Create A New App
    ```

1. 「? Name Your New App:」と聞かれたら、任意のアプリ名を入力してEnter
1. 「Name Your Project」で指定したディレクトリに移動し、serverless.ymlを開き、下記の様にリージョンを設定

    ```serverless.yml
    provider:
      name: aws
      runtime: nodejs20.x
      region: ap-northeast-1
    ```

1. 「Name Your Project」で指定したディレクトリ`$ serverless deploy`コマンドを実行してデプロイ
Pythonが利用しているOpenSSLのバージョン確認

小ネタ

## ワンライナー

```sh
python -c 'import ssl; print(ssl.OPENSSL_VERSION)'
```

## 例

```sh
$ python -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 3.4.0 22 Oct 2024
```

```sh
$ python2.7 -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 1.0.2-chacha (1.0.2k-dev)
```
WebpackのTerserPluginついて

## はじめ
ウェブパックとterserを使用してビルドする時のJS容量の変化測定

## テスト環境
React 18
webpack 5.97.1
webpack-bundle-analyzer 4.10.2

1番設定
console.log + comment 除去
```js
module.exports = override(
    (config) => {
        if (process.env.NODE_ENV === 'production') {
            config.plugins.push(new BundleAnalyzerPlugin());
            config.optimization.minimizer = [
                new TerserPlugin({
                    terserOptions: {
                        compress: {
                            drop_console: true,
                        },
                        output: {
                            comments: false,
                        },
                    },
                }),
            ];
        }
        return config;
    }
);
```

2番設定
console.log + comment 保持
```js
module.exports = override(
    (config) => {
        if (process.env.NODE_ENV === 'production') {
            config.plugins.push(new BundleAnalyzerPlugin());
            config.optimization.minimizer = [
                new TerserPlugin({
                    terserOptions: {
                        compress: {
                            drop_console: false,
                        },
                        output: {
                            comments: true,
                        },
                    },
                }),
            ];
        }
        return config;
    }
);

```


### 결과
使ってなかった場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3981722/82c1c4e6-fc9c-6700-fcf0-47b11249db66.png)

stat size 484.86 KB
parsed size 195.09 KB
Gzipped size 60.45 KB 

使う場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3981722/f5ca0ed6-1023-7d3c-a189-40e5dcfdfbdd.png)

stat size 484.86 KB
parsed size 180.18 KB
Gzipped size 57.33 KB
Twitter(X)にOGP画像が表示されない、更新されない時の備忘録

### **要約**
- **TwitterでOGP画像が表示されない場合**: シェアURLを変更する。
- **OGPの画像自体を変更した場合**: シェアURLと画像名を変更する。

---

### **直面した問題**
TwitterにOGP画像が表示されない問題が発生しました。

- タイポを疑いましたが、確認しても間違いはなし。
- 合計8パターンのうち、半分は正常表示、半分は灰色のサムネイルのみ表示される状態に。

**例**:  
![スクリーンショット 2025-01-17 12.54.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572617/789e908d-3dd1-fa42-00d5-de390ea9ac68.png)


---

### **原因**
- Twitterでは **URLと画像のキャッシュ** を保存する仕様がある。
- 一度取得失敗すると、キャッシュが更新されるまで **灰色のサムネイル** が表示され続ける。
- さらに、OGP画像を更新しても **キャッシュされた旧画像** が表示されてしまう。

**参考**: [Twitter Developer Documentation](https://developer.twitter.com/ja/docs/tweets/optimize-with-cards/guides/getting-started#crawling)

---

### **対処方法**

#### **1. Twitter上でOGP画像が表示されない場合**
- `meta`タグ（`og:image``twitter:card`）やサイトの公開状態を見直す。
-  シェアURLを変更してキャッシュを回避する。


例:  
1. 変更前URL:  
   ```
   https://hogehoge.com
   ```
2. URLにパラメータを付与:  
   ```
   https://hogehoge.com?v=1
   ```

- パラメータ（例: `?v=1`）を付けることでTwitterが新しいOGP情報を取得しに行きます。

※この方法は一時的な対応策。Twitterのキャッシュ更新を待つのが望ましい。



#### **2. サイトのOGP画像を更新した場合**
Twitterは **OGP画像そのものもキャッシュ** しています。

- **対処方法**: OGP画像のURLを更新する。

例:  
1. 変更前:
   - `OGP.jpg` → 修正前画像  
   - `https://hogehoge.com` で表示。
2. 変更後:
   - `OGP_2.jpg` → 修正後画像  
   - `https://hogehoge.com?v=1` で表示。

- **重要**: `og:image` のURLも修正後の画像に更新する。

---

### **まとめ**
1. **画像が表示されない場合**:
   - シェアURLを変更してキャッシュを回避する。
2. **画像を変更した場合**:
   - シェアURLと画像名を変更する。

※Twitterの仕様変更が頻繁にあるため、適宜確認が必要です。

---
Codewars: 7 kyu Check the exam

https://www.codewars.com/kata/5a3dd29055519e23ec000074/train/python

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817969/60981e20-ea6e-0771-f606-c1b07acb569b.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817969/f38b902c-83bc-6cac-3f93-4eb06c53d79f.png)
Hmm...


How about this?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817969/bbfda0d4-12c9-b536-8aad-29648e4c3b5b.png)
Cisco 2960-CG

# コンソール接続の設定
スピード：9600
データ：8bit
パリティ：none
ストップビット：1bit
フロー制御：none

# 初期セットアップの方法
https://qiita.com/shirok/items/4e570819a5d410d76347

```
設定の保存(これをしないと再起動すると設定が消える)
en
write memory
```

```
VLANを設定してトランクポートにする
en
vtp mode transparent(これをやっておかないと、2042は設定できない)
configure
interface GigabitEthernet0/10
switchport mode trunk
switchport trunk allowed vlan 2042
```

```
インターフェースの一覧を簡易表示
show interfaces summary
```
JavaScriptで任意の数の関数を合成

## 概要
任意の数の関数を合成した、新しい関数を返す関数を定義する方法を紹介します。
名前は、compose_all_funcsと仮に決めます。
このcompose_all_funcsは、任意の数の関数を引数に取ります。
compose_all_funcsの戻り値も関数です。
戻り値の関数では、引数valueが与えられたときに、
このvalueに、compose_all_funcsの引数の複数個の関数を、
最初（左側）から適用していった、最終結果を返します。

## 定義
```js
// 引数は任意の数の関数
function compose_all_funcs(...fs){
    // 戻り値の関数
    return function(value){
        // 返す値の初期値は引数の値そのもの
        let result = value;
        for(let idx = 0; idx < fs.length; idx++){
            // 関数を左側から順番に適用
            result = fs[idx](result);
        }
        // 最終結果を返す
        return result;
    }
}
```

## 実行例
```Js
// 数値を2倍にして、数値に3を足して、最後に文字列結合として!を末尾に付加する関数を作成
const composed_function = compose_all_funcs(v => v * 2, v => v + 3, v => v + "!");
console.log(composed_function(100));
```

## 結果
```text
203!
```
Lenovo ThinkCentre M710qにOCuLink端子を付けeGPUを接続する。

# はじめに

最近Youtubeなどで、古いPCに外付けGPU(eGPU)をつけ、ゲーミングPCに魔改造する動画をよく見かけます。
日本ではまだeGPUを付ける人があまりいないためか、手軽な専用ケースは高額ですし、部品を個別に購入してPCに取り付ける、安値な方法もあまり記事に書かれていません。今回これに挑戦したいと思います。

# 用意するもの

今回、僕がeGPUを取り付けるにあたり購入したものを以下に示します。

## 1.PC

まず、僕はTinyサイズのPCが好きなので、Lenovo ThinkCentre M710q Tinyを購入しました。メルカリなどで7000円前後で購入できます。

![lenovo-thinkcentre-m710q-i7th-1667464843.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3914335/8e1cb1cd-cdcc-9c32-2f74-9a226718f78b.jpeg)

ThinkCentre M710q以降のマシンであれば、NVMe対応のM.2端子が本体基板底面部について、OCuLinkの端子を接続できます。
ThinkCentre M700など、これより古いマシンは、BIOSでNVMe対応が禁止されているので、チップセットがNVMeに対応していても、eGPUを取り付けても認識がされません。

## 2.ケーブル

本体に取り付けられるL型のOCulink-M.2NVMe変換ケーブルを購入しました。TinyPCに取り付けるには、ケーブルの長さが20cmのものが、ちょうど良いようです。
Amazonで3000円くらいで売られています。
![51ItTSQFV7L._AC_SL1001_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3914335/4b218162-8f38-de02-34b9-b321248bf80b.jpeg)

## OCulinkアダプター

GPU基板をOCulinkに変換するアダプターです。これにGPUを取り付けます。OCulinkに変換するタイプと、少し前に流行ったUSBやHDMIのライザー端子に変換するタイプのものがあるので、OCulinkに変換するタイプのものを購入します。Amazonで12000円くらいで売られています。

![61q8QNi1ZdL._AC_SL1500_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3914335/f49e6053-1826-7659-d477-a802d6b4bbe6.jpeg)

## GPU

いきなりRTX3090とかで実験して壊すと大損害なので、今回はMSIのRTX2060で実験しました。
MSI GeForce RTX 2060 AERO ITX 6G OCはハーフサイズでとてもコンパクトです。
![71W5O0UD-zL._AC_SL1500_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3914335/6daf1f22-0d81-ac8b-4a3b-afe129078201.jpeg)

## 電源

玄人志向 電源 KRPW-BKシリーズ 80PLUS Bronze 750W ATX電源 KRPW-BK750W/85+　を買いました。
![61hPx6YNZtL._AC_SL1071_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3914335/ce312367-ee7b-a43b-51b2-a5014801e496.jpeg)

# 取り付け方

まず、筐体からCPUファン等をはずし、メイン基板をはずします。基板裏面のNVMe部分に変換ケーブルを取り付けます。
![IMG_5442.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3914335/e31d6979-609a-c88e-efc6-03bf0df0dee4.jpeg)

次に、ケーブルは基板と筐体の隙間から基板の表面に出し、基板を戻の状態にもどします。

![IMG_5443.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3914335/9e2ef7dc-5110-d6e0-68ea-522cf2901f0a.jpeg)

最後に、OCulink端子部分を本体にねじ止めします。

![IMG_5444.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3914335/b577d59a-ee4b-7830-300a-0f43f9c135f6.jpeg)

基板を一度筐体の外に取りはずさないといけないのがめんどうですが、これできれいにOcuLinkケーブルを筐体の外に出すことができます。

# ドライバーインストール
BIOSのディスプレイの設定で内蔵ディスプレイをメインに使う設定を行えば、内蔵ディスプレイとeGPUの両方を使うことができます。
最後にとりつけたGPUのドライバーをインストールすれば、eGPUを使うことができます。

![conpane.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3914335/224ab0d5-4e9d-afcd-e046-d86650c7df6b.png)

OCulinkを使ったeGPUの接続方法の紹介でした。
群馬県🐴ローカルイベント発見アプリ開発日記：3日目

# 3日目：アイデアを形に！要件定義と基本機能の洗い出し (後半)  

皆さん、こんにちは！群馬県ローカルイベント発見アプリ開発者の**🐮 山下**です！  
今日は開発日記【3日目】をお届けします！  

![山道の風景](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637864/26ee1dd7-5fc0-c476-fc88-5d75ef480265.jpeg)  

---

## 今日の作業内容 🎯  

### 1. 洗い出した機能リストの整理 📝  
昨日までにブレインストーミングで出した大量の機能を整理し、優先順位をつけました。  

**削除した機能例**  
- 🗂 **イベントカテゴリー別表示**  
- ⭐ **ユーザーレビュー機能**  
- 💬 **イベント参加者同士のチャット機能**  
- 🗺️ **イベントの地図表示**  

**削除の理由**  
初期段階では必須ではないと判断したため。まずはシンプルで実現可能なものに絞ります。

---

### 2. 各機能の具体的な動作・仕様の定義 ⚙️  

#### **イベント一覧表示・詳細ページ** 📅  
- **動作**：アプリを開くと最新イベントが一覧表示される。  
- **仕様**：  
  - イベント名、日付、場所、サムネイル画像を表示。  
  - タップで詳細ページに遷移し、説明や参加費、主催者情報を確認可能。

#### **キーワード検索** 🔍  
- **動作**：検索バーに入力すると、該当イベントをフィルタリング。  
- **仕様**：  
  - イベント名、カテゴリ、場所で検索可能。  
  - オートコンプリート機能搭載。

#### **ユーザー登録・SNS連携** 👤  
- **動作**：メールアドレスやSNSアカウントで簡単登録。  
- **仕様**：  
  - 登録方法：メール、Facebook、X、Googleから選択可能。  
  - プロフィール画像やニックネームを設定できる。

#### **お気に入り機能・プッシュ通知** ⭐  
- **動作**：お気に入り登録で開催前日に通知を受け取れる。  
- **仕様**：  
  - イベント詳細ページに「お気に入り」ボタンを設置。  
  - マイページでお気に入りリストを管理。  
  - 通知タイミングはカスタマイズ可能。

---

### 3. MVP（Minimum Viable Product）として実装する機能 🛠️  

限られたリソースで最も重要な部分を実現するため、以下の3機能をMVPとして選定しました：  

1. **イベント一覧表示・詳細ページ**  
2. **キーワード検索**  
3. **ユーザー登録・SNS連携**  

この3つが揃えば、ユーザーはイベント情報を収集し、自分専用のアカウントで活用可能に！  
お気に入り機能やプッシュ通知は、後日追加する予定です。  

---

## 今日の感想 💭  

機能の取捨選択はとても悩みました。「これがあればもっと便利なのに！」と思う部分を削除するのは辛かったですが、シンプルな形に絞ったことで、より現実的な目標が見えてきました。  

仕様を具体化したことで進捗を実感すると同時に、「これを実装するのは大変そうだな…」という不安も😅。でも、楽しみな気持ちが勝っています！  

---

## 今日の学びと反省 ✍️  

- **学び**：機能を具体化することで、必要な技術や課題が明確になる。  
- **反省**：機能を詰め込みすぎないように注意。ユーザー目線でシンプルさを意識することが大切！  

---

## 次の目標 🚀  

### 【使いやすさを追求！UI/UXデザインの検討 (前半)】  
- デザインコンセプトの決定  
- 参考となるWebサイトやアプリの調査  
- 群馬らしさを表現する方法の考案  

---

これからも、群馬県を盛り上げる素敵なアプリを作るため頑張ります💪  
ぜひ応援やご意見をコメントやXでお寄せください✨  

---
VSCode 特定のファイルでフォーマットせず保存する

# 概要

VSCodeで特定のファイルのみフォーマットせず保存したいことってありますよね🤔

都度フォーマッターの設定変更をしていたのですが、もっと良い方法があったので記事化しました。

# 手順

1. コマンドパレットを表示（`Cmd` + `Shift` + `P` ）
1. `format` と検索し、「ファイル: フォーマットしないで保存」 をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842674/a2339d8b-f14a-48fd-9119-7cf40ea5a99c.png)

以上です！
優秀なエンジニアを採用するための実践ガイド

# はじめに

はじめまして、大手企業でエンジニアリングマネージャーを務めており、新卒採用の実践経験が6年ほどあります。この記事では、良いエンジニアを採用したいと考えている採用担当者や人事部門の方を対象に、採用の成功に繋がる具体的な方法と戦略を解説します。

# 良いエンジニアとは

良いエンジニアは、単に技術力が高いだけではなく、不確定要素に対応できる能力や、チームでの合わせを考えた気配り、問題解決力を持った人材を指します。例えば、あるプロジェクトで納期直前に大規模な仕様変更が発生した際、迅速に影響範囲を分析し、チーム全体のリソースを再配置して無事納期を守ったエンジニアがいました。このように、予期しない問題にも柔軟に対応できる能力が重要です。

さらに、継続的に学び成長し続ける姿勢が重要であり、これが会社の競争力を高める源泉となります。例えば、最新技術を積極的にキャッチアップし、チーム内で共有することで組織全体の技術力向上に貢献したケースもあります。これには、会社のビジョンやカルチャーに合致した人材の招致も含まれます。



# 採用成功のためのステップ

## 採用の判断軸

採用時には以下のポイントを軸に判断することが効果的です：

1. **技術力**：職務に必要な専門知識やスキルのレベル。

   - 例えば、過去のプロジェクトでどのように技術的な課題を克服したか、具体的なエピソードを確認します。
   - 企業によって技術レベルが異なるので、高ければ高い方が良いですが、最低限の技術力の目線は部門ごとに合わせておくことが重要です。

2. **問題解決力**：未知の課題に直面した際の対応力。

   - 候補者が直面した難題にどのように対応し、どのような結果を出したかの実例を掘り下げます。

3. **コミュニケーション能力**：チーム内での情報共有や協調性。

   - 個人的に重要視しています。エンジニアも一人で仕事をするわけではないため、他者とのコミュニケーションの取り方については、面接時の応対を通じて確認します。
   - また、過去のチーム内での連携方法や意見の対立をどのように解決したかを聞きます。

4. **文化的適合性**：会社のビジョンやカルチャーへの共感度。

   - 志望動機につながります。中途採用では即戦力になるかを重視しますが、新卒の場合は、会社に入って何をやりたいか、どういう未来を実現したいかを面接で確認します。

5. **成長意欲**：学習や自己改善への積極性。

   - 面接時に重要視します。入社後に仕事を通じて成長するのは当然ですが、自ら動けるかどうかで成長曲線の角度が変わります。そのため、入社前に自ら実践している行動を確認します。

## 採用の判断軸に基づく面接の質問リスト

採用時には以下の質問を通じて、候補者の能力や適性を確認することができます：

1. **全般**

   - 前の会社で何をやってきましたか。
     - 行動面接に繋げるための布石。過去のプロジェクトからそのときどんな問題が発生したか、それに対してどうやって対応してきたかを掘り下げます。
   - 転職理由はなんでしょうか。
     - 入社後の転職リスクや、候補者が会社に対して求めていることを理解するために確認します。
   - 将来はどういう道に進みたいでしょうか。
     - 入社後の志向性や、組織にフィットするかを見極めます。また、その道に向かって努力をしているかどうかも深掘りします。
   - 会社に求めるものはなんでしょうか。
     - 組織に合うかどうかを判断します。
   - どういったタイプの人と仕事をしたいと思っていますか。
     - チームでの相性や人間関係のトラブルが起きにくい環境を作るための参考にします。
   - 仕事で気をつけている点はなんでしょうか。
     - 候補者の個性が表れる質問です。

2. **技術力**

   - あなたがこれまでに取り組んだプロジェクトの中で、最も技術的に挑戦的だったものについて教えてください。

   - 使用している技術スタックの中で、特に得意としている技術は何ですか？その理由は？

3. **問題解決力**

   - 直面した困難な問題をどのように解決しましたか？具体例を教えてください。
   - 過去のプロジェクトで一番失敗したと思うのは何でしょうか？その失敗に対してどのような対応をしましたか？
   - 期限前日に仕様の認識間違いが起きて、もう間に合わないような状況になったときどうしますか？

4. **コミュニケーション能力**

   - チームで意見が対立した際、どのように解決しましたか？
   - チームメンバーとの効果的な情報共有方法について教えてください。
   - チームに軋轢が生じた場合、あなたはどのように対処しますか？

5. **成長意欲**

   - 最近学んだ新しいスキルや技術について教えてください。
   - 自身の成長のために行っている具体的な取り組みは何ですか？
   - 過去2年間にあなたが仕事上成長するためにやったことを3つ挙げてください。
   - 技術や知識を最新に保つためにどのような努力をしていますか？

これらの質問を活用することで、候補者の適性をより深く理解することができます。

####

# おわりに

良いエンジニアを採用することは、企業の成長に直結します。本記事では、実際に役立つ具体的な方法や質問例を提示しましたので、ぜひ採用プロセスに取り入れてみてください。行動を起こすことで、より良いチーム構築に繋がることを願っています。