OmniAICreator/Qiita-1.07M huggingface dataset:
Eloquentのfirst~()メソッドシリーズ

## 概要
Eloquentのメソッドに、first~系が多数あるので列挙


## 一覧


### **first()**
   - 最初の1つのレコードを取得します。

```php
$record = Model::first();
```

https://readouble.com/laravel/10.x/ja/eloquent.html#retrieving-single-models

### **firstWhere($column, $operator = null, $value = null)**
   - 指定された条件に一致する最初のレコードを取得します。

```php
$record = Model::firstWhere('column', '=', 'value');
```
https://readouble.com/laravel/10.x/ja/eloquent.html#retrieving-single-models


### **firstOr()**

- 最初の1つのレコードを取得しますが、見つからない場合は指定された条件で新しいレコードを作成します。オプションでカスタムのクロージャも指定できます。

```php
$record = Model::firstOr($columns, $conditions, $callback);
```

https://readouble.com/laravel/10.x/ja/eloquent.html#retrieving-single-models

### **firstOrFail()**
   - 最初の1つのレコードを取得し、見つからない場合は例外をスローします。

```php
$record = Model::firstOrFail();
```

https://readouble.com/laravel/10.x/ja/eloquent.html#not-found-exceptions

### **firstOrCreate(array $attributes, array $values = [])**
   - 指定された条件に一致する最初のレコードを取得し、存在しない場合は新しいレコードを作成します。

```php
$record = Model::firstOrCreate(['column' => 'value']);
```

https://readouble.com/laravel/10.x/ja/eloquent.html#retrieving-or-creating-models


### **firstOrNew(array $attributes, array $values = [])**
   - 指定された条件に一致する最初のレコードを取得し、存在しない場合は新しいレコードのインスタンスを作成しますが、保存はしません。

```php
$record = Model::firstOrNew(['column' => 'value']);
```
https://readouble.com/laravel/10.x/ja/eloquent.html#retrieving-or-creating-models



## 参考
Python ( boto3 ) からAgents for Amazon Bedrockを呼び出す

前回作成したAgentをPythonから呼び出してみます。

https://qiita.com/cyberBOSE/items/b59b6763f24dded7743c

# エイリアスの作成

APIのI/Fを見るとagentAliasIdが必要なようなので、マネコンの該当Agentから`Create Alias`でエイリアスを作成します。

参考資料

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock-agent-runtime/client/invoke_agent.html

https://github.com/aws-samples/agentsforbedrock-retailagent/blob/main/workshop/test_retailagent_agentsforbedrock.ipynb

# プログラム

マネコンからAgentのIDと、`Alias ID`をメモしておきます。
※作成時に指定した`Alias name`ではないので注意

上記の参考資料を見ながらプログラムを書きます。

```Python:agentforbedrock.py
import uuid
import boto3

# Agentへの入力テキスト
input_text:str = "Bedrockで使用可能なモデルは？"

# Agentの定義
agent_id:str = 'XXXXXXXXXX' # ご自身のAgentのID
agent_alias_id:str = 'XXXXXXXXXX' # ご自身のAgentのAlias ID
session_id:str = str(uuid.uuid1()) # 乱数

# Clientの定義
client = boto3.client("bedrock-agent-runtime")

# Agentの実行
response = client.invoke_agent(
    inputText=input_text,
    agentId=agent_id,
    agentAliasId=agent_alias_id,
    sessionId=session_id,
    enableTrace=False
)

# Agent実行結果の取得
event_stream = response['completion']
for event in event_stream:        
    if 'chunk' in event:
        data = event['chunk']['bytes'].decode("utf-8")
        print(data)
```

# 実行結果

```
Bedrockで使用可能なモデルには、Amazonが提供するTitanテキストモデルやTitan画像モデルなどと、
Anthropic、Cohere、Hugging Faceなどのサードパーティモデルプロバイダーのモデルがあります。
```
相変わらず正確性が微妙なRAGになっていますが、ともあれAgent経由でKnowledge baseの検索が行えました。
boto3的にはAgentを呼び出しているのみなので、Agentの中の処理（今回はKnowledge baseのRAG)やLLMは隠蔽されています。

Streamlitでガワを被せるとこんな感じです。

```Python:agentforbedrock2.py
import uuid
import boto3

# Agentの定義
agent_id:str = 'XXXXXXXXXX' # ご自身のAgentのID
agent_alias_id:str = 'XXXXXXXXXX' # ご自身のAgentのAlias ID
session_id:str = str(uuid.uuid1()) # 乱数

# Clientの定義
client = boto3.client("bedrock-agent-runtime")

# Streamlitでガワを被せる
import streamlit as st

st.title("Bedrock AgentからのKnowledge base呼出し")
input_text = st.text_input("このテキストをAgentに送信します")
send_button = st.button("送信")


if send_button:
    result_area = st.empty()
    text = ''

    # Agentの実行
    response = client.invoke_agent(
        inputText=input_text,
        agentId=agent_id,
        agentAliasId=agent_alias_id,
        sessionId=session_id,
        enableTrace=False
    )

    # Agent実行結果の取得
    event_stream = response['completion']
    for event in event_stream:        
        if 'chunk' in event:
            text += event['chunk']['bytes'].decode("utf-8")
            result_area.write(text)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3573242/77221db1-1e48-8579-fe80-09c72d00dd9f.png)


https://qiita.com/cyberBOSE/items/fe66c2049aaa04568d61
re:Invent 2023 Amazon Qに関するセッションでの主要機能まとめ

## はじめに
[Japan AWS Jr. Champions Advent Calendar](https://qiita.com/advent-calendar/2023/jr-champions) 7日目の記事です! 本記事が初投稿となります。
AWS re:Invent2023で「NEW LAUNCH」のセッションを登録したところ、Amazon Qに関するセッションに参加することができたので、セッション中で紹介されていた主要機能についてまとめました。

## セッションタイトル
Bring the power of generative AI to your employees with Amazon Q

## セッション概要
Amazon Qに関する主要機能（key feature）についての説明とデモが行われました。
本記事はセッション中に説明のあった主要機能について簡単にまとめたものです。

なお補足では、Amazon Qで使用されているモデルや対応言語など疑問点を記載していますが、回答は見つかっていないので、分かり次第修正します。知っている方いましたら、コメントいただければ幸いです。

## Amazon Qの主要機能
### Q&A
- エンタープライズのデータから生成された信頼のある回答が得られる
- 自然言語でのやりとりが可能
- ソースの確認が可能
- 回答の履歴を確認することが可能

### ファイルのアップロードと分析
- 文章の要約
- ドキュメントについての質問
- データの解析
- さまざま種類のファイルタイプに対応可能
pdf, docx, csv, ppt, txtなど

### プラグインを使用したアクションの実行
・エンドユーザーはSaasアプリケーションにアクションを実行できる
例として以下のようなものが紹介されていました。
>会話を要約して、Jiraにチケットを作成して

記載されていたSaaSアプリケーション：Salesforce, zendesk,Jira, ServiceNow


### セキュリティ
- 権限をさまざまなレイヤーにふくめることができる
- 有害なアウトプットを防ぐために事前に準備したガードレールを使用できる
- 企業コンテンツへの応答を制限する
- 特定の文字や言い回しをレスポンスに出さないようにブロックできる
#### 〈ガードレール〉
- 事前に定義したメッセージをレスポンスに含めることができる
- メタデータフィルターを使用して、企業コンテンツに対する応答を制限できる
- エンタープライズにおいて、特定のユーザやグループにガードレールを提供することができる

### 使用可能なコネクター
かなりのありました。
Adobe Experience Manager
Alfresco
Amazon S3
Atlassian Confluence
Aurora(MySQL, PostgreSQL)
Box
DB2
Dropbox
Drupal
Custom Connector
FSX for Windows
Github
Gmail
Google Drive
Jira
Microsoft：Exchange, One Drive, SharePoint, Teams, Yammer, SQL Server
Quip
Salesforce
ServiceNow
Slack
Web Crawler
WorkDocs
Zendesk

## 補足
### 【Amazon Qで使用されているモデルについて】
公式ドキュメントには以下の説明がありました。
https://aws.amazon.com/jp/q/faqs/
>Q:Can I choose my own large language model (LLM)?
>A:No. However, AWS uses various foundation models from Amazon Bedrock within Amazon Q.

各々がLLMを選択することはできないとのこと。
さらに複数のモデルを使用しているとのこと

##### 疑問
- それぞれの機能ごとにモデルが異なるのか、1機能の中に複数のモデルが使用されているのかなどが気になった点です。
- 日本語対応はどうなったら対応できるのか（複数のモデルを使用している場合、全てのモデルで日本語対応できてないといけないのでは?）


### 【対応言語について】
公式ドキュメントには以下の説明がありました。
https://docs.aws.amazon.com/amazonq/latest/business-use-dg/supported-languages.html

簡潔にまとめると、
>複数の言語に対応しているが、英語がオススメ

とのこと。

##### 疑問
・複数の言語に対応していると書いてあるが、英語以外の記載がないので、どこまで対応しているのか。
・率直に日本語はいつ対応できるか。
【GAS】知ってますか？！Googleのサービスを自動化するスクリプト言語！Google Apps Scriptについて！

# はじめ
先日、何か面白いことはできないかと思い、サークルメンバーの誕生を祝ってくれるbotを作りました
サークルの連絡はslackを使っているため、slackbotを作ることに！
作成にあたって、GASというGoogleのサービスを使ったのですが、何ができるのか、メリット、デメリットを知らなかったので**今回はGASについて**まとめたいと思います
是非、一緒に学習しましょう！

# 目次
1. GASとは？
1. GASでなにができるの？
1. GASを使うメリット
1. GASを使うデメリット
1. おわり

# １, GASとは？
**Googleが提供・開発しているプログラミング言語**

G が　**Google**で～
A が　**Apps**　で～（Appsとは、アプリのことか、英語弱い、、泣）
S が　**Script**　の略です！　（サービスだと思った！）
<br>
GoogleさんがJavaScriptを元に、GASを開発されているため、
文法はJavaScriptと似ていて学習コストが低いのが特徴！
<br>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3593749/67923cfc-649d-cea4-de9f-f2c412a6825d.png)
<br>

chatGPTに問いかけてみた↑
ほぼJSってことですかね、（笑）
<br>

# 2,GASでなにができるの？
### 外部アプリとの連携と業務効率化
slack、Googleスプレッドシート、Gmail、X、Youtubeなどあるようです！

さーて、どんなことできるのでしょうか。


>slack ×　Googleスプレッドシート => 誕生日祝うぜbot
Gmail => 自動返信
twitter、Youtube　×　Googleスプレッドシート => データ集積　

とか、GASを使ったら様々な業務を効率化できるようです！
GoogleスプレッドシートにXにポストしたいこと貯めてって、毎朝自動的にポストしてくれる機能とか作れたら面白そうですね。

# 3,GASを使うメリット
なんとっても、**無料で使える！！！**
**しかも、？！　環境構築も不要！！！**

必要なのは、**Googleアカウント**と**ネット環境**のみ！
（もう皆さんありますよね？！よし、GASを使いましょう！）

GASは、Googleのサーバーで起動するため、自分のパソコンでプログラムを立ち上げなくても定期的に実行することができます！

また、**疑似的なスクレイピング**が手軽にできます！
スプレイピングとは、インターネット上からデータを抽出する技術のことです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3593749/8198d301-7e9b-f39d-5321-54d57bf93e3b.png)


😏（GAS）

# 4,GASを使うデメリット
**動的Webサイトのデータ収集が苦手な点**です。
ログインとかクリックが必要なWebサイトのデータをスクレイピングすることがやや難しいよう、、
2つ目は**呼び出し回数、処理時間などに一部制限がある点**。
1日に決まった回数までしか、呼び出すことができず、一度の実行で6分間しか実行できません、、
重い処理には、適してないようですね、
Google Workspaceに加入すれば解消できます！

:yum:(GAS) 1360JPY払ってくれれば、もっと働きますよ。

# 5,おわり
Googleさんはこんな偉大なサービスを作ってくれてたんですね！
皆さんもぜひ、遊んでみて下さい！
では、最後にGASを使い作った皆の誕生日を祝うSlackbot「エンタン君」を実行してみたみんなの反応を一部、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3593749/45f8864a-42e0-caab-4f6f-6b144c012e80.png)

治安はいいです、、よ？((多分
<h3><font color="#0000ff">DONE👋</font></h3>
EC-CUBEにオリジナルのファビコンを設置

# 基本環境
EC-CUBE4.2.2

# デフォルト
このファビコンがデフォルト設置
![favicon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1653133/3903a50f-9633-8f5a-7809-9862b9717b79.png)

有りか：
root/html/user_data/assets/img/common/favicon.ico

# オリジナルファビコンの作成
仕様：
ファイル形式：PNG
サイズ：256px×256px
ファイル名：favicon.png

# 拡張子の変更
PNGファイルをローカルに保存したら
コピー
拡張子の変更　.png→.ico

# アップロード
root/html/user_data/assets/img/common/favicon.ico

# ブラウザで確認
キャッシュを削除
↓
再読み込み
↓
タブに表示
Amazon Athenaの超詳細解説

# はじめに
この記事はDevOps on AWS大全の一部です。
DevOps on AWS大全の一覧は[こちら](https://qiita.com/tech4anyone/items/b06f88035d27c6ef13b2)。

この記事ではAmazon Athenaに関連する内容を超詳細にまとめています。

具体的には以下流れで説明します。

- Amazon Athenaとは
- Amazon Athenaの活用
- Amazon Athena for Advance
- Amazon Athenaのベストプラクティス

AWSの区分でいう「Level 200：トピックの入門知識を持っていることを前提に、ベストプラクティス、サービス機能を解説するレベル」の内容です。

# この記事を読んでほしい人
- Amazon Athenaがどういうサービスか説明できるようになりたい人
- Amazon Athenaを採用するときのベストプラクティスを説明できるようになりたい人
- AWS Certified DevOps Engineer Professionalを目指している人

# Amazon Athenaとは
Amazon Athenaは、サーバーレスなクエリサービスであり、Amazon S3に保存されたデータに対してSQLクエリを実行することができます。

![](https://storage.googleapis.com/zenn-user-upload/413ad0ef7efe-20231207.png)

Athenaは、インフラストラクチャの管理やスケーリングに悩まずに、SQLを使ってデータを分析することができるため、簡易なデータ分析ツールとして非常に有用です。

また、Amazon Athenaは一般的に可視化サービスのAmazon QuickSightとセットで使われます。
Amazon Athenaで分析した結果をAmazon QuickSighetでレポーティングやダッシュボードとして利用者に提供するという使い方です。

# Amazon Athenaの活用
## データレイクのクエリ
Amazon Athenaを使用すると、Amazon S3に保存されたデータに対してSQLクエリを実行できます。
これにより、データレイク内の膨大なデータセットから必要な情報を迅速に取得できます。

S3に保存したデータに対してクエリ発行できるので実プロジェクトではBI用途のみならず、インシデント調査にも活用されています。
具体的にはVPC FlowLogsやELB Logsといったネットワーク系のログの分析やCloudTrailのトレイルログといった監査系のログ分析から、不審なアクセスや操作がないかを分析します。

## フェデレーテッドクエリ
Amazon Athena Federated Queryは、異なるデータソースからのデータをAthenaで統合的にクエリできる機能です。

![](https://storage.googleapis.com/zenn-user-upload/5161a20501ef-20231207.png)

対応データソースにはAmazon RDS、Redshift、Aurora、S3などがあり、SQLを使用してこれらのデータソースに対して横ぐしを通したクエリを発行できます。

Amazon Athenaの説明文はこのブログも含めてS3に対してクエリ発行可能という記載が多いですが、このフェデレーテッドクエリを使うことでS3以外のデータソースに対してもクエリ発行をすることができます。

S3以外のデータソースに接続するときにはLambdaの上に構築されるデータソースコネクターを利用する必要があることに注意しましょう。

## 分析用途のダッシュボード作成
Athenaの結果をAmazon QuickSightでビジュアライズすることで、ビジネスインテリジェンスや分析用途のダッシュボードを簡単に作成できます。

これにより、簡易なデータ分析基盤としてAthena＋QuickSight＋S3を用いることができるようになります。
もちろん、ELTツールなどもないので本格的な分析は難しいですが実プロジェクトではこの簡易さが結構重宝します。
具体的には、PoCとしてのデータ分析を行う際に非常に有用です。

手元にあるデータが本当に有用なのかはある程度分析をしてみないとわからないものの、有用性が判断できない時点で重厚長大なデータ分析基盤を作ることは一般的にコストの関係から難しいです。

そのため、簡単に作れるAthena＋QuickSight＋S3の構成が重宝します。

# Amazon Athena for Advance
## パーティショニングの活用
大規模なデータセットに対しては、データのパーティショニングを活用することが重要です。
パーティショニングにより、データを効率的に分割し、クエリの実行速度を向上させることができます。
特に日付や地域などのキーでパーティショニングすることが効果的です。

## AWS Glue Data Catalogの統合
AthenaはAWS Glue Data Catalogと統合されており、データのメタデータ管理が簡単になっています。
Glue Data Catalogを使用することで、Athenaからデータの検索やクエリをスムーズに行うことができます。

## Prestoクエリエンジンの最適化
AthenaはPrestoクエリエンジンをベースにしており、複雑なクエリの最適化や効率的な実行が可能です。
Prestoのクエリ言語に慣れることで、より高度なクエリを作成できます。


## Amazon Athenaのベストプラクティス
最後にAmazon Athenaを利用する際のベストプラクティスをまとめました。

|ベストプラクティス | 詳細|
|--- | ---|
|パーティショニングの活用 | 日付やカテゴリなどでデータを適切にパーティション分割する。|
|圧縮とフォーマット | ソースデータを圧縮し、データ形式はParquetやORC形式を選択する。|
|キャッシュの活用 | クエリ結果をキャッシュし、同じクエリの高速な実行を実現する。|
|クエリの最適化 | 実行計画を検討し、パフォーマンスのボトルネックを最適化する。|

Amazon Athenaはサーバレスなクエリサービスですが、性能を引き出しつつコストを下げるために考えるべきポイントは一般的なクエリサービスと同じです。

データセットの特徴にもよりますが、実プロジェクトの感覚では圧縮とフォーマットがコストと性能の最適化につながります。

元のデータがParquetやORCなどカラムナ形式ではない場合、Glueなどを用いて変換したうえでS3などに保存するとよいでしょう。

# まとめ
この記事ではAmazon Athenaに関連する内容を超詳細にまとめました。

- Amazon Athenaとは
- Amazon Athenaの活用
- Amazon Athena for Advance
- Amazon Athenaのベストプラクティス

次回からはインシデントとイベントへの対応を説明します。
SESで案件に参画するときの心得

## 前置き
私はIT業界に飛び込んでから約20年ほど経ちました。
そのIT業界人生の約8割がSESや派遣で客先常駐でした。
（開発～テストまでやったり、テストだけだったり色々です。）

そこで、SESでアサインされる側の心意気というか私が気をつけていることやメリット、デメリットをお伝えしたいと思います。

## SESとは
まずSESとはなんぞや？ということですがWikiを見てくださいｗ
https://ja.wikipedia.org/wiki/システムエンジニアリングサービス契約

派遣と混同されますが、主な違いは指示系統です。
SESは客先の人間から直接作業指示されることは違法です。
（実際は・・・）
派遣は派遣先の人間から直接指示されることになります。
（だけど自社作業もやらされたりします・・・）

## アサイン前に自社内で確認すること
### 期待値の確認
まずは営業または上長から、自分が何を期待されてその案件にアサインされるのかをよく確認してください。
これができていないとアサインされてから、何をすれば良いのかわからないってことがあります（前述の通り、指示は自社から出るのが正なので）

### 客先に提出している経歴書の確認
また、この際に経歴詐称（違法です）されてアサインさせられる場合もあります。
例えば、プログラム経験がないのに、経験者としてアサインさせられる場合ですね。
実務経験がなく学生時代にプログラム経験がある場合でも実務経験として記載されていたらアウトだと思います。

## アサイン時に実施すること
### 貸与品の確認と状態記録
貸与品（PCや入館証）を受領することもあると思います。
その際、きちんと管理簿を作成してください。
紛失や破損などしてしまうと、始末書ものになりますので。

### オフィスルールの確認
こちらはアサイン時に説明してもらえることが大半だと思いますがもし説明がない場合はこちらから質問しちゃってください。

## 業務遂行中に気をつけること
### 顧客との付き合い方
顧客との距離感を間違えないでください
あまり仲良くなりすぎて、自社の文句など言い過ぎると自社の評判を落とすことになり結果的に自分に不利益になります。まぁ会社の愚痴を言い合うのって楽しいのですがｗ

とはいえ、仲良くなっておけば仕事がやりやすくなるので損はないです。

## SESのメリット
### 幅広い経験が積める（チャンスがある）
色々なサービスやシステムに携わる機会が多いです。
逆にいうと広く浅くになりがちなのですが、色々なことを知れるのは楽しいです。

### 他社の人間と交流ができる
あとサービスやシステムだけでなく、人との出会いも多いです。
中には気の合わない人もいますが、他社の人間と知り合えるのは自分の人生にとってプラスになると思います。

## SESのデメリット
### 好きな仕事をずっと続けられない
メリットの逆になりますが、有期契約であるので１つのサービスやシステムにずっと携われないことが多いです。

### 自社の人間と疎遠になる
客先に常駐することが多いので、自社の人間よりも客先の人間と接することも多くなります。
そうすると帰属意識はどんどん薄れていきます・・・。

### 上司が部下を将棋のコマのように扱うようになる。
こいつは空きアサインだからこの案件に入れちゃえ！ってな感じで人というかモノのように扱われてる気になります。

### 評価が難しい
客先にずっといるので上司（評価者）が現場での様子を確認できません。
そうすると評価基準は単純に単価（売上）になるので、機械的な評価になってしまいます。
（これは人によってはメリットかもしれません）

## 終わりに

正直個人的にはSESはお腹いっぱいですが
SESにはSESのいいところがあるので、今の今までなくならずに続いているのだと思います。

顧客からする人員調整しやすい、SES企業からすると、客先に放り込むだけでお金を貰える（言い方ｗ）
というところでしょうか。

もし、SESは嫌だという場合は入社前にきちんと確認しましょう。

この記事が少しでも参考になれば幸いです。

駄文にお付き合いいただきありがとうございました。
配列へのアクセス順序による処理速度の違いはCrystalにもあるか？

## はじめに

ネタがないので他の人の書いた面白い記事に乗っかります。

https://qiita.com/kikuchi-yzrh/items/56b2368e4473e19ec1d9

記事の内容を要約すると、
二重配列へのアクセス順序を外側から最初にアップデートするのか、それとも内側からアップデートするか変更することでパフォーマンスに大きな違いが出るとのことでした。

> CPU は必要なデータがあるたびにメモリをデータを読み込みにいきます。ただし、CPU からメモリは非常に遠くに存在する上に、メモリの速度よりも CPU の速度の方が圧倒的に速いため、毎回メモリに値をアクセスすると非常に遅くなってしまいます。

## Crystalでもやってみた

上の記事のコードをChatGPTの力を借りて、Crystalに翻訳してみました。そしてベンチマークをとってみました。

```cr
require "benchmark"

# 配列の初期化
array1 = Array.new(10000) { Array.new(10000, 1) }
array2 = Array.new(10000) { Array.new(10000, 2) }

def method1(array1, array2)
  (0...10000).each do |j|
    (0...10000).each do |i|
      array1[j][i] = array2[j][i]
    end
  end
end

def method2(array1, array2)
  (0...10000).each do |i|
    (0...10000).each do |j|
      array1[j][i] = array2[j][i]
    end
  end
end

Benchmark.bm do |x|
  x.report("method1:") do
    method1(array1.clone, array2)
  end
  x.report("method2:") do
    method2(array1.clone, array2)
  end
end
```

`clone` の部分が気になる方もいるかもしれませんが、Crystalでは [`clone` はディープコピー](https://crystal-lang.org/api/1.10.1/Array.html#clone%3AArray%28T%29-instance-method)、[`dup` はシャローコピー](https://crystal-lang.org/api/1.10.1/Array.html#dup%3AArray%28T%29-instance-method)となります。

結果です。

`--release` をつけない場合で

```
               user     system      total        real
method1:   3.721720   0.170310   3.892030 (  3.876282)
method2:   15.440656   0.016409   15.457065 (  15.455674)
```

`--release` をつけた場合で

```
               user     system      total        real
method1:   0.275252   0.150778   0.426030 (  0.406678)
method2:   2.372106   0.000000   2.372106 (  2.367528)
```

となり、いずれのケースでも目に見えて大きな差があることがわかります。
予想通りの結果ですが面白いですね。

この記事は以上です。
モブワークについてお話します！

皆さんこんにちは！
株式会社medibaバックエンドエンジニアでリーダーをしております永原です。
この記事は [mediba Advent Calendar 2023](https://qiita.com/advent-calendar/2023/mediba)の17日目です。

## はじめに
弊社は基本リモートワークで、一部でモブワークを採用しております。
(基本的には、午前はソロタスクやMTG、午後はモブワークの流れです)
様々なモブワークを経験してみて、私が思ったことや今後どうしていきたいか等をお話します！

## モブワークとは
3人以上で集まり、1つの画面を共有して行う開発手法です。
画面を共有し進行するドライバーが1人、他のメンバーはナビゲーターとなりドライバーへ指示を出します。
チーム全員が同じ画面を見て、一緒に問題を解決します。

## 良かったこと
### 参加者全員で設計や相談が出来る
プロダクト参加者全員で設計が出来ることで、別で同期を取る必要がなく、一緒に設計するのでその場で疑問点について確認が出来ます。
また、チーム外とのやり取りについて気になったことや質問したいことをチームで議論した後に話すことが出来るのも良いです。
### バックエンド以外のPRを見る機会が増えた
モブワークでフロントエンド等自分の担当していない領域のPRを見る機会が増えました。
そういったこともあり、自分の担当領域以外への興味、学習意欲も自然と湧くようになっていきました。
### チームメンバーにインフラ講座を開いてもらえた
(モブワークをしていなくても相談することはできると思いますが、一緒に作業していると相談しやすいという意味で)
私は元々インフラの実務経験はなく独学で少しかじっていた程度です。
実際の実務の話を交えながら学べたので、独学よりも楽しくより実践で役立つインフラ知識を得ることができました。
### 属人化を防げる
各自で別々で作業をしている時にありがちだったのが、担当者が体調不良などで休んでいて聞かないとわからないという状態に陥りがちでした。
モブワークですと一緒に進めているしある程度理解した状態でPRや関連資料を見ているので、フォローしやすいと感じました。        
### 雑談は大事という自分にとって新たな発見があった
過去の経験上、お客様先に出向する機会が多く、タスクを早く確実にこなすことが大事、雑談は仕事じゃないからNG(話をふられたら返すぐらいで良い)と思っていました。ただモブワークで一緒にお仕事をする時間が増えてから、淡々とタスクをこなすだけではどこか息苦しさを感じるようになり、物事を円滑に進める上で雑談の大事さを実感しました。

## 大事だと思ったこと
モブワークを進めていく上で、(当たり前かもしれませんが)コミュニケーションが特に大事と感じました。
私はモブワークをはじめるまでは個人の作業に注力し、コミュニケーションにそれほど意識を割いていませんでした。
(MTGの場だったり、適宜必要に応じて会話する程度)
円滑なコミュニケーションが出来ていると、モブワークの良さをより活かしきれると考えています。
例えば以下があげられます。

- 質問がしやすい、それによって不明点が解消されていき、成長していくことが出来る
- ワーキングアグリーメント等で自分の意見を話すことでチームのルールがより充実する
- 苦手、自信がない領域に関しても発言しやすい

リモートワークですと、オフィスに出社するケースと比べ、コミュニケーションについて考えなければいけないことが更に増えてしまいます。
今後もより良好なコミュニケーションをとるために、試行錯誤を進めていく必要があります。

## やってみたこと
### ワーキングアグリーメントを作る
ワーキングアグリーメントは、チーム全員が議論して納得した内容を明文化する、チーム内のルールです。
これはモブワークに限った話ではないですが、チーム内のルールがしっかりしていないと、チームメンバー一人一人が考えなければならないことが増えてしまいますし、同じ作業をしていてもやることがバラバラだったり、相談の手間が都度発生したりと疲弊してしまいます。
ルールがしっかりしていて都度振り返りをしてアップデートをかけていくことで、チームでやることのイメージが湧いて同じ方向を向くことが出来るようになると考えています。
### モブワーク以外に1on1で一人一人の意見を聞く
進捗も大事ですが、モブワークを続けていてずっと完璧で進むことはないと思います。
良いことを続けていったり、課題を改善していくために振り返りをやってはいますが、振り返りはチームメンバー全員が発言するため、時間の制約上、個人の意見を聞きたくてもそれほど深掘りして聞くことができません。
1on1なら2人の時間しか使わないため、気兼ねすることなく、深掘りして話すことができます。
人によって捉え方が全然異なってくるので、ありがたいことに様々な意見を聞くことが出来ました。
もちろん聞いておわりではなく、どういうモブワークで進めていくのが良いかの参考にし、実践するのが目的です。

## 今後やっていきたいこと
### 他チームとモブワークについて意見交換
弊社にはDeveloper’s Communityという社内エンジニアで交流できるイベントがありますので、その場でモブワークについて登壇し、意見交換のきっかけを作りたいと考えております。

## 最後に
モブワークに参加するメンバー全員の理想を叶えることは難しい(人数によっては不可能)です。
ただ、一人一人の意見を聞くことで理想に近づけることや、モブワーク以外でフォローできることがあるかもしれません。
また、良質なモブワークには良好なコミュニケーションが不可欠であると思いますので、より良好なコミュニケーションをとっていくにはどうしたら良いか引き続き試行錯誤していきたいです。
目指すものが一人よがりにならないためにも、チームメンバー一人一人の意見に耳を傾け、チームメンバーが楽しく快適に働けるようにしていきます！
拙い文章をここまで読んでくださった方、ありがとうございました！
(ちょっと気が早いですが)良いお年を！
ComponentPropsWithoutRefとJSX.IntrinsicElementsの違いってなに？

型の定義で`ComponentPropsWithoutRef`と`JSX.IntrinsicElements`というものがあることを知りました。
違いがわからなかったので調べてみました。

## ComponentPropsWithoutRefとは？
指定したHTML要素のPropsの型を取得します。
この型は、HTML要素の全てのネイティブ属性をPropsとして取得します。

## JSX.IntrinsicElementsとは？
Reactの型定義の一部で、HTML要素のPropsの型を定義するために使用します。

## 2つの型の違いは？
`ComponentPropsWithoutRef`は、型を取得するのに対して、`JSX.IntrinsicElements`は、型を定義します。

:::note warn
は？って感じですよね…私も同じ感情を持ちました…
具体的な例で確認してみたいと思います。
:::

例えば下記のような書き方だとエラーになります。

```typescript
export interface Props extends JSX.IntrinsicElements['li'] {
  specialProp?: string;
}
```

下記の記述方法だとエラーになりません。
```typescript
export interface Props extends ComponentPropsWithoutRef<'li'> {
  specialProp?: string;
}
```

エラーの内容は下記のとおりです。

> インターフェイスが拡張するのは、オプションの型引数が指定された識別子/完全修飾名のみです。

TypeScriptの制限で、`type`は直接的に拡張できるのに対して`interface`はできないとのことです。

https://typescriptbook.jp/reference/object-oriented/interface/interface-vs-type-alias

## エラーを出さずに`JSX.IntrinsicElements['li']`を利用する方法
`JSX.IntrinsicElements['li']`を使いつつ、エラーを出さないで拡張した型を作る方法を紹介します。

```typescript:解決策①
type listItemProps = JSX.IntrinsicElements['li'];
export interface Props extends listItemProps {
  specialProp?: string;
}
```
一度type（Type Alias）を利用して、`JSX.IntrinsicElements['li']`の方に名前をつけます。
その上でextendsするとエラーは発生しません。

interfaceを使わずtypeを利用するとJSXの記述でも拡張ができる
```typescript:解決策②
type Props = JSX.IntrinsicElements["li"] & {
  hogehoge: string
}
```
interfaceではなく、type（Type Alias）を利用します。
`&`を利用して型を拡張することで解決策①よりもシンプルに書けます。

## 【ComponentPropsとJSX.IntrinsicElementsの違い】まとめ
まだ紐解けてない部分はありますが、`type`を利用するか`interface`を利用するかで選択が変わりそうだと思います。

一般的には`type`は柔軟で`interface`はオブジェクトの型を定義する時に用いられるようです。

適切な型定義の方法を選べるようになるために引き続き精進します。
Reactの基本：PropsとStateの理解

## はじめに
Reactの魅力の一つは、コンポーネントベースのアーキテクチャにあります。
このアーキテクチャにおいて、コンポーネントの動作や表示を制御するために「Props」と「State」が使用されます。これらはReact開発において核となる概念になるのでまとめてみました。

## Props
### Propsの概要
Propsは、親コンポーネントから子コンポーネントに渡されるデータの集まりです。
Propsは、コンポーネントに対して外部から与えられるデータや設定を表します。

### Propsの特徴
不変性: Propsはそのコンポーネントに渡された後、変更されることはありません。子コンポーネントはPropsを直接変更することはできません。
コンポーネントの再利用: 同じコンポーネントを異なるPropsで再利用できます。

Propsの具体的な使用例
```react
// Propsを受け取る関数コンポーネント
function UserProfile(props) {
  // Propsを使用してUIを描画
  return (
    <div>
      <h1>{props.name}</h1> {/* props.nameを表示 */}
      <p>{props.description}</p> {/* props.descriptionを表示 */}
    </div>
  );
}

// 親コンポーネント
function App() {
  // UserProfileコンポーネントに異なるPropsを渡して再利用
  return (
    <div>
      <UserProfile name="太郎" description="エンジニア" />
      <UserProfile name="花子" description="デザイナー" />
    </div>
  );
}
```

## State
### Stateの概要
Stateは、コンポーネント内で管理されるデータです。Stateを使うことで、コンポーネントはユーザーインタラクションや時間の経過などに応じて、その表示を更新することができます。

### Stateの特徴
可変性: Stateはコンポーネント内で変更可能です。この変更は通常、ユーザーのアクションに応じて行われます。
カプセル化: Stateは通常、それを持つコンポーネントに限定されます。他のコンポーネントから直接アクセスされることはありません。

Stateの具体的な使用例

```react
// Stateを使用するクラスコンポーネント
class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = { seconds: 0 }; // Stateの初期化
  }

  componentDidMount() {
    // コンポーネントがマウントされたらタイマーを開始
    this.interval = setInterval(() => {
      // 1秒ごとにStateを更新
      this.setState(prevState => ({ seconds: prevState.seconds + 1 }));
    }, 1000);
  }

  componentWillUnmount() {
    // コンポーネントがアンマウントされる前にタイマーをクリア
    clearInterval(this.interval);
  }

  render() {
    // Stateを使用してUIを描画
    return <div>経過時間: {this.state.seconds}秒</div>;
  }
}
```

## PropsとStateの違い
### Props
親コンポーネントから渡されます。
コンポーネントの外部インターフェースを表します。
不変であり、コンポーネント自身では変更されません。

### State
コンポーネント内で宣言され、管理されます。
コンポーネントの内部状態を表します。
可変であり、コンポーネントのライフサイクルに応じて更新されます。

## まとめ
PropsとStateはReactのコンポーネントを構築する際の基本的な要素です。Propsはコンポーネントに対する外部からの入力を提供し、Stateはコンポーネント内部で管理されるデータを扱います。これらを適切に理解し使用することで、動的でインタラクティブなUIを構築することが>できます。
macOSで5000番ポートが既に使われている問題の解決方法

1. macOSの設定画面を開く
1. airplayで検索する
1. AirPlay Receiverのチェックを外す

![CleanShot 2023-12-07 at 09.29.17@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7565/a047e41c-5700-a458-82d4-d13edd3250bf.png)
アニメ・漫画から見るAIの進化

## AIの進化の発想はどこから生まれる？
AIがどのように進化するのか、その発想はどこから出てくるのかを想像した時、複雑な数式や深層学習の理論を研究するハイスペックなエンジニアたちを思い浮かべる人も少なくないと思います。しかし、もしかしたらAIの未来を描く最大のインスピレーションはデスクから離れたところ、アニメや漫画の中にあるかも知れません。

## アニメ・漫画でのAIの存在と現実のAIの進化

「えっ、それってどういうこと？」って思う方も多いと思います。少しアニメ界の昔話に話を戻してみましょう。
振り返ってみると、AIは実現される遥か昔から様々なアニメや漫画などの世界で登場してきました。「鉄腕アトム」や「ドラえもん」が代表として挙げられるでしょう。その当時、AIはまだ現実として存在していませんでしたが、これらのキャラクターはロボットとして寄り添い教えてくれる友達みたいな存在として登場しました。

それから時間が流れ、少しずつ技術が進むにあたり、このアニメや漫画でのAIもより現実味を帯び、かつ詳細な設定や役割まで持つようになってきます。例を挙げると、「ロックマンEXE」というコンテンツが2000年代に登場しました。ロックマンEXEでは、AIは単純な命令を実行するロボットから一歩進化し、人間と共感し合い、独自の情報を処理するWEB上のエージェントとして描かれています。面白いことに、このエージェントは現在のOpenAIのチャットボット、ChatGPTの機能によく似ているものとなっており、AIユーザーインターフェースの先駆けでもあると言えます。
（十数年も前からAIエージェントと人間の共存を描いていたクリエイターがすごいですね）

▼ロックマンEXE：人とAIが相棒として存在するコンセプト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625415/94f1218b-3393-67d4-accf-cdea8e08d7d8.png)

このように、AIの進化はアニメや漫画に登場するキャラクターやその役割を再現する形で進化してきた部分もあるのではないかと考えています。

ではアニメや漫画から今後のAIの進化を予測してみましょう。
私が特に気になってるのが、「ソードアートオンライン」で描かれた「プロジェクト・アリシゼーション」です。これは「ボトムアップ型AI」という新しいAIを開発するプロジェクトであり、現在の「トップダウン型AI」の様に人が指示した内容を学習するわけではなく、指示をすることなく、人と同じように体験や経験を通じて自ら学習していくタイプのAIを仮想世界（文明シミュレータ）上で自然学習させて成長させようというプロジェクトになります。

個人的には、この「ボトムアップ」AIという体験や経験から学ぶというコンセプトは、自己学習、自律性という新たなAIの誕生のヒントになるのではと考えています。

▼プロジェクト・アリシゼーション上で登場する仮想世界（文明シミュレータ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625415/9ab9d751-f398-9891-3d54-13e7a42d7367.png)


## まとめ
上記の様に、アニメや漫画はただのエンターテインメントではなく、AIの進化の道筋を示す道しるべであり、私たちが未来にどんなAIを想像するかのヒントを与えてくれる存在かもしれません。たまにはデスク上での議論を一休みして、最新のアニメや漫画を楽しむのも良いかも知れませんね。それが次のAI革新を生むきっかけになってくれるかもしれません。
「NLPの原理と道具」を読んだ (注意：自然言語処理ではありません)

この記事はアドベントカレンダーの **エンジニア積読消化** の16日目の記事です。


https://qiita.com/advent-calendar/2023/unread-books



# 積んだきっかけ




<a href="https://www.amazon.co.jp/NLP%E3%81%AE%E5%8E%9F%E7%90%86%E3%81%A8%E9%81%93%E5%85%B7%E3%80%8C%E8%A8%80%E8%91%89%E3%81%A8%E6%80%9D%E8%80%83%E3%81%AE%E5%BF%83%E7%90%86%E5%AD%A6%E6%89%8B%E6%B3%95%E3%80%8D%E5%BF%9C%E7%94%A8%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB-%E3%83%95%E3%82%A7%E3%83%8B%E3%83%83%E3%82%AF%E3%82%B9%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E3%82%B8%E3%83%A7%E3%82%BB%E3%83%95%E3%83%BB%E3%82%AA%E3%82%B3%E3%83%8A%E3%83%BC/dp/4775942107?_encoding=UTF8&qid=&sr=&linkCode=li2&tag=newta-22&linkId=a9ba69c61dfc4acafd199c7b98086455&language=ja_JP&ref_=as_li_ss_il" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4775942107&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=newta-22&language=ja_JP" >
NLPの原理と道具</a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=newta-22&language=ja_JP&l=li2&o=9&a=4775942107" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />


買った理由としては、コーチングに興味があったときに聞いたことがきっかけだったと思います。
少し読んだのですが、洋書独特のエピソード文や言い回しで、テンポの悪さを感じて読むのをやめてしまいました。
このとき、別のコーチング的な本も数冊が積まれていたので、そちらに興味が移っていったと思います。


# 読んだきっかけ

会社の同僚からNLPを学んでから考え方を変えることができたよ！という話を聞いて、この本があったなと思って読むことにしました。 その人のように自分もなりたいと感じる部分が多くあり、そのヒントが少しでも得られればという思いで、かなりモチベーション高く読もうと感じていました。

出会いに感謝！

ちなみに同僚の記事の中にNLPに触れる良い記事があったので、こちらに貼っておきます。

https://note.com/dora_e_m/n/na4681982f670


# 本書の感想

### 結論
今すぐ思考の観点を変えられるような非常に役に立つことが載っていて、特にコーチング的な役割をする人にはオススメです！


ただ、積読の理由になった洋書特有の文章の読みづらさはありました。
エピソードの中で理解を深めることができたものも多くありましたが、ちょっと自分には合わないと感じるエピソード文は若干読み飛ばすこともありました。

### NLPとは
まずエンジニアがNLPと聞いて思い浮かぶのは自然言語処理(Natural Language Processing)だと思います。私もそうなのかな？と思ってしまいました。

これは全く別物で、神経言語プログラミング (Neuro Linguistic Programming)です。
プログラミングと付いていますが、プログラミング言語ではありません。人間が持っている特性に注目した学術領域になります。人間にプログラムされた特性を紐解いていきます。

ひとりひとりの受け取り方というのは様々な要因でフィルターされていて、外界のモデルで起きたことに対して、その一部しか知覚することが出来ないとされています。
ピカソに「ありのままを描かないのですか？」と問う人に、ピカソは「ありのままですよ」と答える様子がなどで説明されていました。また、「パンの一欠片をどのように捉えるかはあなたが腹ペコであるかどうかで変わります」のように、受け取る側の状態によって、同じ現象の見え方が全く変わってしまうことがあります。

### トピック

ここでは面白かったいくつかのトピックを紹介します。


◆ 学習の四段階
１．無意識的無能（知らないしできない）
２．意識的無能（知っていてもできない）
３．意識的有能（考えるとできる）
４．無意識的有能（考えなくてもできる）

◆ 目標は肯定的な表現にしなければならない
脳は否定の文章を実行することは難しい
カンガルーを考えないでくださいと言ったときに、この文章ではカンガルーを考えることを思い浮かべてしまう。本当にカンガルーのことを考えないようにするには、別の肯定的なことを考える必要がある。

◆ コミュニケーションは相手の反応で決まる
あなたが伝えようとした意図とは関係なく。
「あなたは誠意を持って影響を及ぼすことが出来ますか？」
「その影響はあなたの価値観に一致しますか？」

◆ リフレーミングと意味の変換
人間は意味を求めてきた。
出来事が生じる、しかし、我々が起こりそうな結末を予測することによって、それに意味を与えるまでは重要ではない。


# おわりに

エンジニアから見えている景色と他の人から見えている景色は大きく違うことがあります。
それらの前提を前提と認識して、伝えるための観点の変化を起こしてくれるような１冊だと思います。

内容は今回は書ききれないほどの良いトピックがありました。ここに書いたトピックの数倍の面白いトピックがあり、気になったらぜひ読んでみて欲しいです。


見方が変われば行動も変えることが出来ます。エンジニアリングマネージャがエンジニアにどのような観点を持って伝えれば良いのか、エンジニアが別の職種の人にどのような観点をもって技術を説明すればよいのか。

技術を説明するということは、相手に理解してもらうための説明義務をエンジニアが持っているということに繋がっていると思います。相手が理解してくれない、分かってもらえない、と残念に思うことがあったなら、NLPについて少し知ってみるのも良いかと思います。
Javascriptの変数宣言について

久しぶりにJavascriptの作業をする際、
よく `let` と `const` の機能が、どっちがどっちか分からなくなります。
そのため`var`を含め、まずはそれぞれの機能をおさらいします。

<dl>
  <dt>var</dt>
  <dd>
・再宣言や再代入が可能<br>
・変数の巻き上げによってエラーを出さない<br>
・非推奨ではないが、下記で対応可能であればそちらを使う。
  </dd>
  <dt>let</dt>
  <dd>
・変数を宣言する時<br>
・再代入が可能<br>
・巻き上げ時にエラーが発生
  </dd>
  <dt>const</dt>
  <dd>
・定数を宣言する時<br>
・再宣言も再代入もできない<br>
・巻き上げ時にエラーが発生
  </dd>
</dl>

英単語を覚えていれば何となく分かりそうですが、
私はとっさに出てこないため、何かいい覚え方を考えてみました。

無理やりですが、`const`を「co [こ] てい（固定）」と覚えれば、しばらく経っても覚えていられるかな…。
（そもそも英単語を覚えればOKなのですが）

次回、Javascript作業時にこれらを覚えていられるか試してみます。
失業期間にAIに挑戦しよう: GPTと未来の技術への扉

### はじめに
現代のテクノロジーの進展は驚異的なスピードで進んでおり、特に人工知能（AI）はその最前線にいます。この分野はまだ発展途上であり、これから学ぶ人にとって大きなチャンスがあります。失業期間を利用してAI、特にChatGPTのような技術を学ぶことは、未来のキャリアに大きな影響を与える可能性があります。

### 1. AI技術の基礎知識: ChatGPT
ChatGPTは自然言語処理を利用した強力なAIモデルで、会話形式での情報提供、文章作成、質問への回答など幅広い機能を提供します。この技術を学ぶことは、AIの基本的な理解を深めるとともに、実際の応用例を体験する絶好の機会です。

### 2. GPTPlusについて
一般的なスキルアップスクールでは、1日のトレーニングに数万円かかることが多い中、GPTPlusへの月額3000円の課金は、**コストパフォーマンスに優れた学習方法**と言えます。この手頃な価格で、ChatGPTを含むAI技術への深い理解と実践的なスキルを身につけることができます。

GPTPlusは、基本的なAIの知識から応用まで、多岐にわたるトピックをカバーしています。ユーザーは自分のペースで学習を進めることができ、AI技術の迅速な進化にも柔軟に対応することが可能です。この低コストで高品質な学習環境は、特に自己投資にコストを抑えたいと考える人々にとって、大きなメリットを提供します。

### 3. AI学習のリソース
AIを学ぶためには、ChatGPTを活用するのが一番です。質問を投げかけることで、基本的な概念から応用技術まで幅広い知識を得ることができます。また、オンラインコースやチュートリアルを通じて、より体系的な学習も可能です。
> chatGPTとはなんですか？

> 私はソフトウェア系エンジニアです。何に活用できますか？

### 4. 企業におけるAIの活用と課題
企業がAI技術を活用する際、特に情報漏洩のリスクは大きな懸念材料です。例えば、ChatGPTなどのAIツールは、ユーザーからの入力を学習に使用する可能性があり、これには機密情報の共有が含まれることがあります。このため、OpenAIのような企業では、情報保護のための厳格なガイドラインを設けています。しかし、これらのセキュリティ対策により、企業がAIを導入するプロセスは遅れることがあります。

安全なAIの導入には、セキュリティ対策と倫理的な観点が重要です。データ保護のための厳格なポリシーとともに、AIの責任ある使用を確実にするためのガイドラインを設けることが不可欠です。これにより、AI技術の可能性を最大限に活用しつつ、リスクを最小限に抑えることができます。

### 5. 失業期間にAIを学ぶメリット
1. **最先端のエンジニアになれる:** AI技術を学ぶことは、最先端のエンジニアになるための一歩です。特に、PCやスマートフォン、YouTubeのように一般に普及することが予想されるGPT技術を習得することは、将来的なキャリア形成に大きな影響を与えます。
2. **スキル取得:AI** 技術の習得は、新たなスキルを身につける絶好の機会です。これにより、自身のスキルセットを強化し、より多くの機会を引き寄せることができます。
3. **社会貢献:** 便利なAIアプリケーションを作成することで、社会への貢献も期待できます。これは、**2010年代のYouTuber**のように、新たな時代の波に乗る絶好のチャンスです。

### まとめ
失業期間は、新しい技術を学び、将来のキャリアを豊かにする絶好の機会です。AI、特にChatGPTのようなツールを活用することで、技術の深い理解と実践的なスキルを身につけることができます。この機会を活かして、AIの世界への第一歩を踏み出しましょう。

## 宣伝
https://chat.openai.com/g/g-l1cAnHy7S-chun-xia-tukusi-tsukushi-harugasumi

https://chat.openai.com/g/g-RoREYAB0U-zhan-dou-de-lun-po-combative-arg

https://chat.openai.com/g/g-Nx5puN68A-generative-ai-examiner
斜めの線でスタイリッシュにかっこよくする【エンジニアデザイン心理学】



# スタイリッシュ、躍動感が欲しい時 

斜めスタイリッシュ

<img width="80%" src="https://liginc.co.jp/wp-content/uploads/2013/11/diagonal.jpg"> 

細い線だと洗礼されたデザインになる。

## サンプル オリンピック公式サイト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1678228/63019d34-67d0-f657-9e53-5335737d81dc.png)

https://internet.watch.impress.co.jp/docs/news/1188106.html


### 参考

<a href="https://www.amazon.co.jp/%E3%81%82%E3%82%8B%E3%81%82%E3%82%8B%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%80%88%E8%A8%80%E8%91%89%E3%81%A7%E8%A6%9A%E3%81%88%E3%81%A6%E8%AA%B0%E3%81%A7%E3%82%82%E3%81%A7%E3%81%8D%E3%82%8B%E3%83%AC%E3%82%A4%E3%82%A2%E3%82%A6%E3%83%88%E3%83%95%E3%83%AC%E3%83%BC%E3%82%BA%E9%9B%86%E3%80%89-ingectar/dp/4844368427?returnFromLogin=1&linkCode=li3&tag=oreilly10book-22&linkId=3b2e94c616b4f9addf69256b0cf60812&language=ja_JP&ref_=as_li_ss_il" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4844368427&Format=_SL250_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=oreilly10book-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=oreilly10book-22&language=ja_JP&l=li3&o=9&a=4844368427" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
BigQueryストリーミングインサートしているテーブルをコピーする

BigQueryでテーブルをコピーするためには以下のような方法があります。

https://cloud.google.com/bigquery/docs/managing-tables?hl=ja#copy-table

しかし、ストリーミングインサートをしているテーブルに対してこの方法を使う場合は注意が必要です。

例えば、以下のテーブルの行数は通常のストレージに存在する18,606,187行とストリーミングバッファに存在する858,098行の合計である19,464,285行です。

![スクリーンショット_2023-12-07_8_49_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/5aa7713d-08d2-ab26-4631-f95ae46f2520.png)

通常のテーブルコピーをするとストリーミングバッファの行数がコピーされず、18,606,187行のみがコピー対象になります。
そのため、ストリーミングインサートをしているテーブル場合は以下のような方法でコピーする必要があります。

```sql
create table <destination table> as select * from <source table>;
```

ただし、この方法は通常のテーブルコピーと異なり、スキャン料金が発生したり（オンデマンドの場合)、QUERY用のBigQueryのSlotを消費したり(Editionsの場合)するため、その点に注意が必要です。
基本情報技術者試験に落ちた新卒文系エンジニアが2カ月でSAAとDVAに合格した話

# はじめに
こんにちは。記事を開いてくださりありがとうございます。
8月に基本情報技術者試験を受けて、アルゴリズムの点数が足りず落ちた新卒文系エンジニアです。
そこから10月にSAAの勉強を始めて下旬に合格、さらにDVAの勉強を始めて12月上旬に合格したため記録に残したいと思います。

# プロフィール
- 仕事内容
    - R&D。フロント・バックエンド両方扱っています。(SAA取得前はAWSはほぼ触ったことがなかった)
    - これからAWSに触れる数が増えるため勉強を開始しました
- 所有資格
  - AWS Certified Solutions Architect - Associate(以下SAA-C03)
  - AWS Certified Developer - Associate(以下DVA-C02)
  - 教員免許。笑(小・中学国語・高校国語・高校書道)
- IT試験受験履歴
  - 基本情報技術者試験(23/8/11受験)：不合格(得点はその場。正式には)
  - SAA-C03(23/10/29受験)：合格(23/10/30発表)
  - DVA-C02(23/12/02受験)：合格(23/12/02発表)

# SAAの記録まとめ
以下SAAの記録をまとめたものになります。
  - 結果：**738点**(720点合格)
  - 勉強前の知識レベル：**CLFの問題集400/1000点**(EC2とS3とDynamoDBしか知らなかった)
  - 勉強時間：**55~60時間**
  - 勉強開始から本番までの日数：**28日**
  - 解いた問題数：**約800問**(重複あり)
  - 勉強方法：**Udemyでインプット+Udemy問題集・TechStockでアウトプット+参考書で間違えたサービスの復習**
  - かかったお金(受験費用8250円除く)：**7050円**(参考書+TechStock)
  - 試験終了から結果が出るまでの時間：**24.5時間**


振り返るとかなり効率悪く勉強していたなぁと思います。勉強開始時点ではEC2、S3、DynamoDBの概要しか知らなかったので、まずはCLF(クラウドプラクティショナー)の勉強から始めればよかったなと。これに気づいたのが勉強を始めて2週間後で、CLFの問題集を解いたら400/1000点という悲惨な状態でした。。笑(上にその数字を書きましたが、勉強開始時点ではもっと低いと思います)
CLFは受けないにしても、ある程度の点数が取れるようになってからSAAの勉強をするのがおすすめです。

あとは社内で開かれていたSAA勉強会(5~6人グループで週2回ほど開催)で、開催ごとに1人サービス内容をまとめて発表する機会があり、そこで自分の番はアウトプットでき、ほかの人の番ではインプットができたので、複数人で勉強会を開くのもおすすめです。

# DVAの記録まとめ
続いてDVAの記録をまとめたものです。
  - 結果：**801点**(720点合格)
  - 勉強前の知識レベル：**SAA合格(ラインギリギリ)レベル**
  - 勉強時間：**30~35時間**
  - 勉強開始から本番までの日数：**28日**
  - 解いた問題数：**約865問(重複あり)**
  - 勉強方法：**AWS DVA講座(2時間)+TechStockでアウトプット**
  - かかったお金(受験費用8250円除く)：**0円(SAAの時に買ったものを使用)**
  - 試験終了から結果が出るまでの時間：**3時間**

DVAはSAAの時と違って、**インプット0.5割アウトプット9.5割**といった割合で勉強しました。(SAAの時はインプット7割アウトプット3割)
SAAの時もやっていましたが、間違った問題のサービスの仕組みをノートに書いて覚えていきました。(あくまで覚えることが目的なのできれいには書いてないですが。。)
あとは会社でパートナー限定の講座をAWSの方が開いてくださったのでそこに参加しました。ただそこで1からインプットしたというよりかは、理解が曖昧だったところを深めるようなイメージでした。

# おわりに
改めて受験した2回を振り返ってみて、SAA・DVAどちらも800問近く問題を解いていたけど、勉強時間が倍近く違うことに驚きました。元の知識の少なさと、SAAの問題の範囲の広さからインプットをたくさんしなければならない(DVAは範囲が狭い)ことでこんなに変わるのかとびっくりです。
AWSのAssociateは、IT初学者でもサービスや利用方法を覚えたら解けるものしかないので、勉強時間さえ確保できれば取れる資格かなと思います。
ただ、私自身、今回の資格取得に向けてハンズオンを使った勉強はほとんど行わなかったため、実務に向けてハンズオンでもっと勉強する必要があるなと思っています。
次はSOAに向けた勉強と、SAA・DVAの復習としてハンズオンも行っていく予定です。あとは基本情報も今年度中にはリベンジします、、！
最後まで読んでくださり、ありがとうございました。

※ちなみに受験費用が半額なのは、半額キャンペーンをSAAの時に使えたのと、SAA合格時に特典としてもらった半額チケットがあったので、そちらを利用しました。
ACE Renewal Lab Exam からメールが来た

# 背景
・ACE Renewal Lab Exam からメールが来た。
・GCPのAssociate Cloud Engineer certificationの更新のための作業が必要そう
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637037/cc340046-66e2-0439-5f73-454dc368f2bf.png)

# 課題
・何をやったら良いかいまいちわからない
・ラボのレベル感がいまいちわからない

# 解決方法
・Register後に送られてくるメールより、Qwiklabs上でラボ課題を5件解く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637037/ba74c6ce-a30a-75d6-b3eb-7f42d3f5b8d7.png)

・1件あたり10分～20分程度
→・時間にあまり余裕がないため、事前に手順のイメージをある程度持ってからラボを開始した方がいい。
　・全部のラボを一気にやらなくても良さそう。日をまたいで1ラボずつ実施できた。
・基本的には下記の方法で対応可能なレベル
　・各ラボに記載されているタスクを、タスクごとにそのままコピペしてググる
　→GCPの公式ページで手順が書いてある
  ・上記でイメージが湧かないときはChatGPTにもタスクをコピペして尋ねる
  →上記の公式ページと照らし合わせながら、不足手順がありそうであれば更問しつつ
  　手順を作成する
　・labを開始して確認済みの手順を試す
　→エラーが発生した場合は、エラーをそのままChatGPTにコピペして手順を更新してもらう。
 　また、「Allow allって書いてあるけど具体的な設定方法は、、」のようにChatGPTへの訪ね方を変えてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637037/ed43e0e0-877f-8999-62b7-41d0d26fb3f0.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637037/4d96f5bc-5661-5ca0-524d-40fe7768b27f.png)

# おわりに
labはやり切れたけどこれでちゃんと更新されるのか、、
IBM i アーキテクチャー：実行管理 ジョブ状態の遷移

## IBM i のジョブ状態は3種類　（活動状態　待機状態　不適格状態）

IBM i の実行管理の基本を説明します。
前の記事 [活動レベル中でのCPUのディスパッチ](https://qiita.com/gomAnomalocaris/items/d6f485a80772affd98f6) で説明したようにIBM i OS上でシステムやユーザーのタスク・スレッドがCPUを同時に使用できる最大数はプール（メインメモリの論理的な区分単位）毎の最大活動数や *SBSサブシステム毎の最大活動数などで制限されています。
CPUを使用可能なタスク・スレッドの状態を活動状態と呼びます。CPUを使用可能でない状態には待機状態（ロング・ウェイト状態）と不適格状態の2種類があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/fd5d9a15-db5e-8f28-f091-e4f81006294b.png)

### 活動状態
活動状態は正しくはジョブ（タスク・スレッド）がCPUを使用できる資格を持っている状態を意味します。実際にはCPUを使用している状態（活動ジョブ）と短時間待機状態の2つの状態に分かれます。

### 待機状態（ロング・ウェイト状態）
代表的な例として5250端末ジョブでのユーザーからの画面入力待ちがあります。他にもメッセージ待ち、装置待ち（物理的な入出力装置からの応答待ち）、データベースのレコード待ちなどがあります。

### 不適格状態
活動レベルに空きが無いため、活動レベルに空きができるのを待っている状態。

### ジョブ状態の遷移
#### 活動状態 → 待機状態
ジョブが以下の理由でロング・ウェイト状態になった状態。ジョブは活動レベルとメインメモリ上のページ（PAG）を開放し、ウェイト待ち行列に移されます。
    ・5250画面に対するEXFTM命令、WRITE命令実行時
    ・データベースファイルのレコードロック時
    *MSGQ メッセージ・キューからのメッセージ待ち

#### 待機状態 → 活動状態
5250端末で実行キーが押された場合、テープの読み込みが完了した際などにロング・ウェイト状態が解除され活動レベルの空きを確認します。空きがある場合、活動状態に戻ります。

#### 待機状態 → 不適格状態
ジョブがロング・ウェイトを終了したが、活動レベルに空きがない場合、不適格状態に移されます。

#### 活動状態 → 不適格状態
スレッドやタスクがタイムスライスエンドに到達すると、タスクは不適格待ち行列にある優先順位が等しいか高いジョブに活動レベルを与えられるように優先順位が1/128下げられます。そして不適格待ち行列のジョブと比較して優先順位が低い場合は不適格状態に移されます。

#### 活動状態 → 活動状態
優先順位が高いジョブが不適格待ち行列に無い場合は、タイムスライスエンドに到達したジョブはリセットされたタイムスライスと1/128減じられた優先順位で活動レベルを保持し続けます。

#### 不適格状態 → 活動状態
活動レベルに空きができると、不適格待ち行列で実行待ちの最も優先順位の高いジョブが活動状態になります。

※次の記事:[ジョブ状態遷移の具体例](https://qiita.com/gomAnomalocaris/items/447546ea1d9ac39e2c85)で具体的な例をあげて説明したいと思います。
[LangChain]FAISSベクトルストア検索でメタデータを活用する

# はじめに
LangChainのFAISSベクトルストア検索でメタデータを使った検索方法についてまとめました。

# 実装例
"おはようございます"、"こんにちは"、"こんばんは"という日本語と英語のテキストをサンプルデータとして使用します。
metadataには日本語か英語かという情報が付与されています。

## メタデータを使った類似度検索
```python
from pprint import pprint
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
from langchain.docstore.document import Document

chunk_size = 500
embeddings = OpenAIEmbeddings(chunk_size=chunk_size)

documents = [
    Document(page_content="おはようございます", metadata=dict(lang="ja")),
    Document(page_content="こんにちは", metadata=dict(lang="ja")),
    Document(page_content="こんばんは", metadata=dict(lang="ja")),
    Document(page_content="Good morning", metadata=dict(lang="en")),
    Document(page_content="Good afternoon", metadata=dict(lang="en")),
    Document(page_content="Good evening", metadata=dict(lang="en")),
]

faiss = FAISS.from_documents(documents, embeddings)
docs = faiss.similarity_search("こんにちは", k=1)
pprint(docs)
```

"こんにちは"で検索すると日本語の"こんにちは"がヒットします。
```terminal
[Document(page_content='こんにちは', metadata={'lang': "ja"})]
```

検索対象を英語に限定してみます。
similarity_searchのfilterに検索対象をdict型で与えます。今回は英語のみを対象に検索したいので、lang="en"としています。

```python
docs = faiss.similarity_search("こんにちは", k=1, filter=dict(lang="en"))
```

"こんにちは"ではなく"Good afternoon"がヒットしました。
```terminal
[Document(page_content='Good afternoon', metadata={'lang': 'en'})]
```

:::note info
dict(hoge="", fuga="")のようにするとAND検索ができますが、OR検索はできないようです。
:::


## 対象の文章を全て取得する
最後に対象のメタデータが付与された文章を全て取得する方法を紹介します。
エンべディングされたデータはdocstore._dictに格納されています。
このデータに対してフィルタリング処理を行えば、必要な文章を全て取得することができます。

```python
def find_by_metadata(
    faiss: FAISS, filter: dict[str, Any] | None = None
) -> dict[str, Document]:
    if filter is None:
        return faiss.docstore._dict

    response = {
        key: item
        for key, item in faiss.docstore._dict.items()
        if all(item.metadata.get(k) == value for k, value in filter.items())
    }

    return response


docs = find_by_metadata(faiss, dict(lang="en"))
pprint(docs)
```

```terminal
{'54883d65-fef7-44d3-b00b-fd56d8bd52d0': Document(page_content='Good morning', metadata={'lang': 'en'}),
 'f7ea9f81-044b-4f3d-b17b-f46a7e3c3058': Document(page_content='Good afternoon', metadata={'lang': 'en'}),
 'fbdd669d-b295-4a43-94d3-182823201b58': Document(page_content='Good evening', metadata={'lang': 'en'})}
```

このようにメタデータが英語の文章を全て取得することができました！
品質管理における、当たり前の徹底の重要性

## はじめに
現在入社6年目で、5年ほど品質管理をやっています。
品質管理業務をやっている中で、**当たり前の徹底ほど重要なものはない**と痛感しました。
その具体例3点について共有します。
特に新人開発者の人に読んでもらえると嬉しいです。
## 1.アップデートの社内フローを遵守する
弊社では、最低週に1度のアップデートを実施しています。
その中で「何曜日の何時までに何々の段階まで確認を終わらせてください」というものがあります。
**この期日を開発部全体で守ってもらうことが、品質向上に繋がります。**

### なぜ期日厳守が重要か？
例えば、金曜日の19時までに「検証込みで開発完了」が期日だとします。
このとき、確認や修正が間に合わず「金曜の19時10分に完了しました。アップフロー載せてください」と依頼が来ることがあります。
時々、「19時も19時10分も、その10分間で品質が大きく変わるわけがないのだから、開発速度優先でどんどん通すべきではないか」と思う人がいます。
しかし、これは大きな間違いです。
### 割れ窓理論
割れ窓理論とは
>1枚の割られた窓ガラスをそのままにしていると、さらに割られる窓ガラスが増え、いずれ街全体が荒廃してしまうという、アメリカの犯罪学者ジョージ・ケリング博士が提唱した理論

です。
これは品質管理にも当てはまります。
「10分が許されるなら、30分」「30分が許されるなら1時間」...のように、伸び伸びになってしまいます。
その開発物の品質が仮に良かった場合でも、その期日意識では**次回以降の開発物で開発計画・テスト計画などの段取りが上手く行かず、後工程でのしわ寄せが起きる可能性が高い**です。
また例外が認められた場合、人は「次回もこの手法で許される」と無意識に思ってしまう生き物です。
**「今回の開発計画・テスト計画の何がマズかったか」と反省して改善してもらうためにも、安易に例外的に認めるのは避けるべき**です。
(もちろん、やむを得ない事情があり柔軟に対応した方が良い場合もあります。ここで重要なのは「ルールが形骸化しないようにすべき」ということです)

## 2.開発チケットに、実装内容・確認内容を詳細に記載する
そもそもの話、**業務で開発したものや記載したチケットの所有権は、原則会社に帰属します。**
「私物ではなく会社のもの」という意識で、「将来的に自分以外の人がソースコードやチケットを読んだとき、理解できるか」という観点で取り組んでください。
**特にIT業界では、同じ業務を数年後・数十年後も同じ人がやり続けることはほぼあり得ません。**
今やってることが数年後の後任者が見てわかるか、という"思いやり"で整備しましょう。
(緊急対応などで忙しければ後日対応でもよいですが、リマインダーなどを掛けて後でやるのを忘れないようにしましょう)


## 3.開発チケットを期日切れにしたままにしない
チケットは基本、期日切れにならないように管理してください。
期日切れのタスクがあると「やらなきゃいけないと分かっているが、今はできない」という状態になります。これが重なると期日切れのタスクに対する警戒レベルが麻痺し、**重大なタスクの漏れがあったときに気づけなくなります。**
ハインリッヒの法則で言及されているように、**重大なやらかしは確率の問題**なので、いつかくる「しまった」のリスクを減らしていきましょう。
>「ハインリッヒの法則」とは、労働災害の分野でよく知られている、事故の発生についての経験則。 1件の重大事故の背後には、重大事故に至らなかった29件の軽微な事故が隠れており、さらにその背後には事故寸前だった300件の異常、いわゆるヒヤリハット（ヒヤリとしたりハッとしたりする危険な状態）が隠れているというもの。

たまに「自分の頭の中や別のシートで完璧に管理しており、現状タスク漏れは起きていない。全く困っていない」という人もいるかもしれません。
ただ2で述べたように、そのタスクを一生ずっとその人がやるはずがありません。諸事情で突然引継がれた場合、**後任者は「どれが実際大丈夫な案件で、どれが期日切れしている案件なのか」が分からなくなり、問題が発生します。**

## 終わりに
**品質管理では「他者にどれだけ当たり前のことを当たり前にやってもらうか」というのも重要なファクター**だと思います。
障害の中には、日頃から当たり前を徹底していれば防げた、というものが多くあります。
人数が多くなっても、これらの当たり前が当たり前に守られるようにしていきましょう。
2023年のReactに関する最新の動向やベストプラクティス

## 1.クラスコンポーネントと関数コンポーネント:
クラスコンポーネントはES6クラスとライフサイクル関数を使用し、オブジェクト指向プログラミングに慣れている開発者には理解しやすいです。一方、関数コンポーネントはJavaScriptの関数を使用し、状態やライフサイクルを持たないため、代わりにフックを使用します。useState, useEffect, useSelectorなどのフックはコードをより簡潔で理解しやすくしています​​。

## 2.CSSとUIコンポーネントライブラリ: 
スタイリングには、CSS-in-CSS、CSS-in-JS、Utility-First-CSSのいずれかをシナリオに応じて選択できます。Tailwind CSS、Styled Components、EmotionなどのライブラリはReactでのスタイリングに異なるアプローチを提供します。UIコンポーネントライブラリでは、Ant Design、Material UI、Mantine UIなどが人気で、ボタン、ドロップダウン、ダイアログ、リストなどの事前に作成されたコンポーネントが含まれています​​。

## 3.Reactにおける状態管理: 
TanStack Query、SWR、Redux Toolkit Query、Apollo ClientなどのライブラリがReactアプリケーションでのサーバー状態の管理において人気があります。それぞれに独自の強みがあり、REST APIやGraphQLなど異なるシナリオに適しています​​。

## 4.フォーム処理: 
フォーム処理には、2023年現在、React Hook Formが推奨されています。これは性能が良く、使いやすく、YupやZodなどの検証ライブラリとの統合も容易です。Formikなど他のライブラリと比較して、フォームデータの処理に必要なコード量を減らすことができます​​。

## 5.テスト: 
Reactアプリケーションのテストには、単体テストにはVitestやReact Testing Library、エンドツーエンドテストにはPlaywrightやCypressが推奨されています​​。

## 6.React 18の新機能: 
React 18では、ウェブアプリケーションのパフォーマンスを向上させるための多くの新機能が追加されました。NextJSやRemixなどのメタフレームワークの採用が重要になっており、フロントエンドからバックエンドへのコードの移行が進み、フルスタックアプリケーションの開発がより楽しくなっています​​。

## まとめ
これらの点から、2023年のReactは関数コンポーネントとフック、効率的な状態管理とフォーム管理、堅牢なテスト実践に焦点を当てています。また、現代のフレームワークやツールとの統合は、パフォーマンスとスケーラビリティのあるウェブアプリケーションの構築に向けて、進化するエコシステムへの理解と適応の重要性を強調しています。

## 最後に
マイページ画面については、どんな物を表示させるかについては、サービスの活性化に大きく関係します。
個々人に最適化されたマイページに関して、導入したレコメンデーションエンジンがいつの間にか邪魔なコンテンツになってる可能性があります。
新しいコンテンツにエンカウントできる様なレコメンデーションエンジンの導入について検討してみるべきだと思います。

これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
N+1問題のヤバさとその解決策

# N+1問題のヤバさとその解決策

この言葉を聞いてダメ！絶対！と感じる人、どんな問題なんだろ？と感じる人さまざまいると思います。

この記事ではN+1問題のヤバさと対応方法にも言及していきます。

## N+1とは

どんな問題になるかというと性能の問題になります。

例を見ながら説明していきます。

X(旧Twitter)を簡単にしたサービスに以下のようなusersとtweeetsテーブルがあるとします。

**users**

| id | name |
| -- | -- |
| 1 | John |
| 2 | Nick |
| 3 | Mary |
| 4 | Nina |
| 5 | Kevin |
| 6 | Kate |

**tweets**

| id | user_id | tweet |
| -- | -- | -- |
| 1 | 1 | Good morning |
| 2 | 1 | Hi |
| 3 | 1 | Hello |
| 4 | 1 | Wow |
| 5 | 1 | Great |
| 6 | 1 | Fine |
| ... | ... | ... |

このDBから各tweetとtweetしたユーザーをクライアントに返却する場合はどうするでしょうか？

### N+1問題を引き起こすパターン

tweetsテーブルからレコードを全て(Nレコードとする)取得してからループ処理で各user_idでusersテーブルから1件ずつレコードを取得

という処理考えたとします。確かにtweetsテーブルのuser_id情報からusersの情報を取得することはできます。

しかしクエリの発行数に着目してみるとどうでしょうか？

クエリは

- tweetsテーブルからレコードを全件取得 : 1回
- ループ処理で各user_idでusersテーブルから1件ずつレコードを取得 : N回

から合計N+1回発行します。

Xのようなサービスでは毎日数多くのTweetがされるので、性能問題が起きるのは明らかですね。

### じゃあどうするか

対応は2パターンあると考えられます。

- RDBのJoinを使う
- Eager Loadを使う

#### RDBのJoinを使う

DBにある程度精通した方ならJoinでテーブルを結合する手法を思いつくでしょう。

```sql
select * from tweets left join users on tweets.user_id = users.id;
```

とすると1クエリで全データを取ることができます。

#### Eager Loadを使う

Eager LoadほとんどのORMが持っている機能で解決することもできます。

Eager Loadを使う場合、処理とクエリ発行は以下の流れになります。

1. tweetsテーブルのレコードを取得: 1回
1. tweetsテーブルのレコードからuser_idをリスト化: 0回（ORM内部の処理）
1. 上で生成したuser_idリストにあるusersテーブルのレコードを取得: 1回
1. tweetsのuser_idとusersのidのリレーションからまとめた構造を作る: 0回（ORM内部の処理）

Eager LoadはGoのORMパッケージのGORMでこの機能を使えます。

例を書いてみます。

```go
// usersテーブルの構造体
type User struct {
    ID    uint `gorm:"primaryKey"`
    Name  string
}

// tweetsテーブルの構造体
type Tweet struct {
    ID     uint `gorm:"primaryKey"`
    UserID uint
    User   User
    Tweet  string
}

// tweetsからusersをEager Load
func getTweetsWithUser() []Tweet {
    tweets := make([]Tweet, 0)
    db.Preload("User").Find(&tweets)
    return tweets
}
```

このように`getTweetsWithUser()`をコールするとEager Loadが実行されTweet構造体にUser情報が格納され、かつクエリは2回のみになります。

皆さんは性能問題を引き起こすことのないようにこの対応を覚えておきましょう。
BigQueryのスプレッドシート外部表をterraformで管理する

以下のドキュメントで説明されているスプレッドシートを外部表にする設定をterraformで管理してみます。

https://cloud.google.com/bigquery/docs/external-data-drive?hl=ja

まずは、この記事と同様にディレクトリ階層とテーブル階層が等価になるような設計にします。
https://qiita.com/shiozaki/items/71272a71c5a2b6bba93a

```
sheets_tables
├── データセット名1
│   ├── テーブル名1.yaml
│   └── テーブル名2.yaml
├── データセット名2
│   └── テーブル名3.yaml
└── データセット名3
    └── テーブル名4.yaml
```

それぞれのYAMLファイルの中身は以下のような構造をとっています。

```yaml
source_uri: <連携したいシートのURL①>
sheet_name: <連携したいシート名称(スプレッドシート画面の最下部にあるタブの名前)②>
range_top_left: <連携したい範囲の左上のセル③>
range_bottom_right: <連携したい範囲の右下のセル(下方向に無制限にしたい場合は数字を省略)④>
schema:
- name: <カラム名1>
  type: <カラム名1の型>
  mode: NULLABLE
- name: <カラム名2>
  type: <カラム名2の型>
  mode: NULLABLE
...
```

　それぞれの記載内容を図示します。

![スクリーンショット_2023-12-07_8_37_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/74568a62-e341-6c7f-3e0c-fe2bc34575e0.png)

最後に以下のtfファイルをterraform applyすればYAMLファイルに対応したスプレッドシート外部表が自動的に作成されます。

```terraform
resource "google_bigquery_table" "external-sheets" {
  for_each = fileset("${path.module}/sheets_tables", "*/*.yaml")

  project    = local.project
  dataset_id = split("/", each.value)[0]
  table_id   = trimsuffix(split("/", each.value)[1], ".yaml")

  external_data_configuration {
    source_format = "GOOGLE_SHEETS"

    autodetect = false
    schema     = jsonencode(yamldecode(file("${path.module}/external_tables/${each.value}"))["schema"])

    google_sheets_options {
      skip_leading_rows = 0

      range = join("", [
        yamldecode(file("${path.module}/external_tables/${each.value}"))["sheet_name"],
        "!",
        yamldecode(file("${path.module}/external_tables/${each.value}"))["range_top_left"],
        ":",
        yamldecode(file("${path.module}/external_tables/${each.value}"))["range_bottom_right"],
        ]
      )
    }

    source_uris = [
      yamldecode(file("${path.module}/external_tables/${each.value}"))["source_uri"]
    ]
  }
}
```
Swift未経験から一人前のiOS開発者として扱われるまでに取り組んだこと

本記事は[SwiftWednesday Advent Calendar 2023](https://qiita.com/advent-calendar/2023/swift-wednesday)の7日目の記事です。
昨日は@ojun_9 さんでした。

### はじめに
初めまして。23新卒で入社し、現在Swift歴5ヶ月ほどになる@startaiyoと申します。
現在の配属先でiOS開発に携わるまでSwift経験はほとんどなく、配属決定の7月にほぼ初めてSwiftを触るといった状態でした。
そこから部署の方々の助けを借りながらも様々な取り組みを行い、ようやくSwiftに慣れ始めてきたかな、というところまで辿り着けました。プロジェクトでも他の方同様、一機能単位のタスクを割り振られるようになってきたり、レビュアーにアサインされ始めたりと、一人のiOSエンジニアとして扱っていただけるようになってきました。
そんな中、今回は今まで自分がしてきた取り組みを振り返らせていただきました。
新しくSwiftを始める方々のお役に少しでも立てれば幸いです。

## 自分が今までやってきたこと
今から紹介する内容は、本業であるプロジェクトでのiOS開発業務と並行して行ってきたものになります。

### 1. iOS Developer Roadmap 2023に沿って勉強し、内容をアウトプット
始めたての頃は本当に何もわからなかったので、ひとまずメンターさんに教えていただいたこちら↓のロードマップに沿って学ぶことにしました。

https://medium.com/@andres.carort/ios-developer-roadmap-2023-330fd5cb7479

やり方としては上から順に概要が掴める程度に調べ、調べた内容を部署のチャンネルにアウトプットし、先輩方からFBをいただくというものでした。
ロードマップの網羅性がかなり高いこともあり、これが個人的にはかなり役に立ったと思っているため、そのメリットをお伝えします。

**1. プロジェクトのキャッチアップが早くなった**
これはすごい感じるところで、自分のプロジェクトに使われているモジュールやライブラリ、コードの書き方そのものに至るまで、これは何をしているコードなんだろう、と疑問に思うことが圧倒的に減りました。
特に、デザインパターンを学んでいたお陰で、プロジェクト内でたくさん使われているRxSwiftの理解がしやすくなったのは強く実感しました。

**2. 技術選定をしやすくなった**
個人開発をしていて技術選定に迷った際、自分の過去のアウトプットを参考にできています。例えばデータの保存がしたい時にどれを使おうかと考えた際、RDBのような関連性を持たせながらローカルにデータ保存するならRealmがいい、とすぐに決めることができます。

**3. 低レイヤーな知識も身についた**
スレッドやメモリなど、iOS開発では必須だが今まで自分が避けてきたような低レイヤーな知識も、しっかり学んで確固とした知識として身につけることができました。

**4. Swiftのトレンドも同時に把握できた**
これは先輩方からいただけたFBを通じてといった意味合いが強いですが、今この技術は使われていない、逆にこれが使われている、といった知識を得ることができました。これは比較的古いプロジェクトに携わっていただけではわからなかったと思います。

他にも副次的ではありますが、アウトプットに対する抵抗がなくなったのは大きかったかなと思います。

### 2. プロジェクトのソースコードを眺め、コードと挙動の関連付け
こちらは後述する個人開発と同時並行ではありますが、起動した際に初めに呼ばれるAppDelegateからその先の各画面に至るまでどのように動いているのかを順を追って確認しました。その確認作業の際にも、ロードマップで学んだApp Statesの話やReachabilityなどのフレームワークに関する知識が役に立ちました。

### 3. 学んだことを活かして個人開発
今まで1.や2.で学んだことを具体的に使えるレベルにするべく、簡単な個人アプリの作成に取り組みました(現在進行中です)。
まずは2.のプロジェクトのコードを真似て、立ち上がり〜トップ画面表示までのアプリの基本的な動きを再現することができました。これはかなり効果があり、プロジェクトのコードに慣れたことにより、**実際のプロジェクトでの開発速度が上がりました。**
そして現在は1.で学んだ網羅的な知識の概要を実装の具体レベルに落とせるよう、様々な技術を取り入れながらアプリを制作しています。

## やっておけばよかったこと
**1. コードを早めに書き始めるべきだった**
個人開発のコードを書き始めたのは、ロードマップの学習が終わった後でした。
ただ、調べてしばらく経つとアウトプットした内容もほぼ忘れてしまいますし、実際に使うタイミングになって初めてasync/awaitが便利なことや、SPMが手軽で管理がしやすいことなど、概要を学んだだけでは気づけなかったメリットを感じることができました。

**2. コードベースで正しい書き方を最初から学んでおくべきだった**
何を持って正しいのかという話でもありますが、勉強した内容をコードで記述する際、どんな書き方をするのがベストなのかは早めに知っておくべきでした。
自分が携わっているプロジェクトは昔からあるもので、中には今ではそんな書き方しない、というコードもあったりします(例えばカスタムクラスがゴリゴリに使われていたりなど)。
そのため、いつ頃書かれたコードかに注意しながら、勉強した内容の技術を使っているアプリのソースコードを見るなどして知見を蓄えていれば尚、アプリ開発の速度も上がったような気がします。

## 今後の展望
Swift初学者の方が、プロジェクトに携われるレベルに早く到達するためのお手伝いができればと思っています。
特に、ロードマップで扱われている技術の具体例がコードベースで見れるといいだろうなぁと強く思うので、とにかく今作成しているアプリをそれらの技術を盛り込んで完成させ、ソースコードとともに技術の説明を加えた資料を作成して公開することを目標に活動しています。
また、こうした対外的なアウトプットは初めてなので、今後も継続していきたいと思いました！

明日は上記取り組みでいつもお世話になっている、@uhooiさんです！よろしくお願いします。