OmniAICreator/Qiita-1.07M huggingface dataset:
PostgreSQLのインデックス戦略

[失敗から学ぶRDBの正しい歩き方](https://www.amazon.co.jp/%E5%A4%B1%E6%95%97%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6RDB%E3%81%AE%E6%AD%A3%E3%81%97%E3%81%84%E6%AD%A9%E3%81%8D%E6%96%B9-Software-Design-plus-%E6%9B%BD%E6%A0%B9/dp/4297104083)を読み、データベースに対してインデックスをどの状況で付与するべきかを学んだのでアウトプットしたいと思います。


## インデックスって何?
データベースにおけるインデックスは、データベースの検索性能を上げるために付与させる、索引だと考えてもらっても構いません。
### インデックスを貼るメリット
具体的にインデックスを貼ることで、特定のレコードを取得したい際に、その場所させわかっていれば無駄なデータベースの検索を済まなくてよくなることができます。


### インデックスを貼るデメリット
更新処理に関するパフォーマンスが低下します。

具体的に該当インデックスの付与されているカラムの更新処理を走らせた場合に、インデックスに対しても更新処理が行われるため、

```レコード数　× インデックスの更新処理時間```

の書き込み作業の余分な負荷が起きます。


また、インデックスのデータのために，ディスク領域を用意しておくことが必要です。

以上が、無闇にインデックスはつけてはいけな理由になります。
次に、いつ(When) インデックスを付与していけばいいかを説明していきます。


## 基礎的な概念とindexの必要性
PostgreSQLでは、B-tree、Hash、GiST、SP-GiST、GIN、BRINといった複数の種類のインデックスを使用可能です。
一般的に、PostgreSQLではデフォルトのB-treeが使用されます。


PostgreSQLにおけるB-treeにおいて
```SELECT * FROM bookss WHERE book_id = 2500;```
のSQL文が読み込まれた際に以下のようにして対象のデータが検索されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880777/27c7fbf4-1790-e905-6786-ddeb3903205a.png)
)

そして上記の図のように`book_id=1500~3000`のデータを100個のブロック（1ブロックに15のレコードが存在)に振られる他場合、この100ブロックをフルスキャンしないといけなくなり、検索効率が悪くなってしまいます。

### BTreeeでINDEXを利用したとき
INDEXを利用した際は100ブロックの中の必要な1ブロックを利用するために、4ブロックを取得すれば良くなるため、１枚目のINDEXがない時と比較して単純に計算して25倍以上検索効率が良くなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880777/6fffd1e8-3002-9c13-9991-feeff5c24f59.png)

## インデックスをどんなタイミングでつければいいか
以下の2つの条件を満たした時に、indexを貼るリターンが見込めます。

### 1.検索結果がテーブル全体の20%未満
インデックスは少数のレコードを取得する際に最も効果的になります。
テーブル全体の大部分を返すクエリには、インデックスにはあまり効果が見込めないです。
テーブル全体の20%未満かどうかを判断するときに`カーディナリティ`を意識すると良いです。

#### カーディナリティとは
カーディナリティは列内のユニークな値の多さを指します。カーディナリティが高いということは、その列の各値が一意であることを意味します。逆に、カーディナリティが低いとは、列内で値の重複が多い状態を指します。

以下のような重複が少ないデータはカーディナリティが低いと言えます。
例えばgender列に1 = 男性, 2 = 女性のように2種類のデータしかない場合、カーディナリティは低いと言えます。この場合、データが均等に分布している（50:50）場合は、検索結果がテーブルの50%以上を占めるため、インデックスはあまり効果的ではありません。しかし不均等な分布（例: 男性99%, 女性1%）の場合、少数派のデータ（この場合は女性）を検索するときにインデックスは非常に効果的です。

### 2.検索対象のテーブルが多い場合
数万から数十万行が目安となってくるらしいです。
1000行程度のテーブルの場合はINDEXから参照するより、テーブルスキャンが効率的なケースが多いとのことです。
例えば、都道府県マスタのような47行しかないようなテーブルにはINDEXは使用しないほうがいいです。

## 結論
インデックスを付与するときに、付与する際の恩恵が受けられるかどうかを判断することが重要だと考えております。
リターンかコストを比較してインデックスをつけていくことが大事だと思いました。


## 引用
https://www.amazon.co.jp/%E5%A4%B1%E6%95%97%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6RDB%E3%81%AE%E6%AD%A3%E3%81%97%E3%81%84%E6%AD%A9%E3%81%8D%E6%96%B9-Software-Design-plus-%E6%9B%BD%E6%A0%B9/dp/4297104083
TypeScriptでPartialを利用する

## はじめに
TypeScriptで基本型に対し、すべてOptionalにするPartialを紹介します。

```ts:index.ts
// Person 型の定義
type Person = {
  name: string;
  age: number;
  address: string;
};

// PartialPerson 型の定義（Person のすべてのプロパティがオプショナル）
type PartialPerson = Partial<Person>;

// PartialPerson 型のオブジェクトの例
const person1: PartialPerson = {
  name: "Alice"
};

const person2: PartialPerson = {
  age: 30
};

const person3: PartialPerson = {
  address: "123 Main St"
};

const person4: PartialPerson = {};

// 各オブジェクトの内容をコンソールに出力
console.log(person1); // { name: 'Alice' }
console.log(person2); // { age: 30 }
console.log(person3); // { address: '123 Main St' }
console.log(person4); // {}

// このファイルは TypeScript (.ts) ファイルとして保存し、
// TypeScript コンパイラを使用して実行する必要があります。

```

```shell:実行結果
~/develop/react/typescript_node$ ts-node index.ts 
{ name: 'Alice' }
{ age: 30 }
{ address: '123 Main St' }
{}
```
AWSのコスト体系について学び直す

この記事は、[CyberAgent Group SRE Advent Calendar 2023](https://qiita.com/advent-calendar/2023/ca-sre)の25日目の記事です。
昨今、為替の影響でクラウドコストに頭を悩ましている人も多いのではないでしょうか？
FinOpsなど、クラウドコスト最適の為の取り組みを弊社でも日々行なっています。
今回は、AWSのコスト体系について理解を深めるためにまとめてみました。

# 利用料金の分類
AWSの利用料金は、下記の二つのタイプに大枠分けることが出来ます。
- リソースの「使用量」に対する料金
  - ネットワーク転送量、ストレージ使用量、リクエスト量、データ処理量など
  - リソースの利用料に比例して費用が増加する
- リソースの「存在」に対する料金
  - インスタンス起動、ストレージサイズ、エンティティの存在など
  - リソースの存在時間に比例して費用が増加する

しかし、提供されるサービス毎に課金条件が異なるので、単純に「使用量」と「存在」に分類することはできません。また、一般的な使用料金だけでなく、オプション料金や無料利用枠なども考える必要があるため、とても複雑です。
各サービスには、必ず料金説明のページがあるので、どういった課金体系なのか確認してから、サービスを利用しましょう。

# コストの把握
AWSでは、コストを把握、最適化するためのサービスやツールが用意されています。
- [AWS Billing Console](https://aws.amazon.com/jp/aws-cost-management/aws-billing/)
  - AWSから発行された請求を確認できる
  - サービス毎に集約された月毎の利用コストを確認できるが、詳細までは分からない
- [AWS Cost Explorer](https://aws.amazon.com/jp/aws-cost-management/aws-cost-explorer/)
  - アカウント配下の料金について調べられる、
  - 多機能なので、使いこなすのが難しい
- [AWS Trusted Advisor](https://aws.amazon.com/jp/premiumsupport/technology/trusted-advisor/)
  - コスト最適化のヒントを提案してくれる
  - ただし、なぜそのリソースがあるかを知ることはできない

# 無駄なコスト
コスト削減する上で、無駄なコストを見つけることが重要だと思います。では、無駄とは何なのでしょうか？
下記は、考えられる一例です。
- 放置されているSnapshot
- 適切でないストレージクラスが設定されているS3オブジェクト
- オーバープロビジョニング
  - E.g. 余裕があり過ぎるAutoScalingの設定、大き過ぎるインスタンスタイプ、多過ぎるEBS容量
- 無駄な通信
　　- E.g. AZ間通信、Cache出来るのに、されていない通信

この様な無駄は、Cost Explorerでは、本当に無駄なのかは分からないと思います。
無駄な可能性のあるリソース情報は、Trusted Advisorのコスト最適化に出力してくれるので、まずはそちらを活用するのが良いです。

# 費用対効果
コスト最適化にかかるコストやそれによって得られるインパクトも意識する必要があります。下記は、作業コストとインパクトを元にした、費用対効果の優先順位になります。
| 作業しやすさ | 作業内容 | インパクト |
| :--- | :--- | :--- |
| 1 | 放置リソースの削除 | 全リソースにかかっているコスト削減 |
| 2 | インスタンスサイズの見直し | E.g. 一つ下のサイズにすることによってコストは半分になる |
| 3 | ストレージクラスの見直し | E.g. S3のオブジェクトクラスやEBSタイプ変更による差分のコスト削減 |
| 4 | ネットワークコストの見直し | E.g. AZ間通信コストの削減 |
| 5 | API、サービスコストの見直し | E.g. アーキテクチャ変更による差分のコスト削減 |

費用対効果の話をしましたが、過剰なリソース削減は信頼性とのトレードオフであることを忘れてはいけません。特に、パフォーマンスやロバスト性への影響考慮しないと信頼性低下に繋がってしまうこともあります。
コスト削減は必ずしもリソースやアーキテクチャの見直しだけではないと思います。また、それぞれの事業フェーズにあったコスト最適化が重要だと思います。今回の記事の元ネタになっているAWSのコスト最適に向けた取り組み（FinOpsの文化醸成など）についても、来年は発信していければと思っているので楽しみに待っていてください。

# 最後に
まずは今回CyberAgent GroupのSREで、Adevent Calendarをやろうという話をして、快く執筆してくれたメンバーには深く感謝を伝えたいです。
素晴らしい記事が沢山あるので、是非[他の記事](https://qiita.com/advent-calendar/2023/ca-sre)も見ていただけると嬉しいです。
2024年は、今年以上にCyberAgent GourpのSREの取り組みを発信していければと思っているので、お楽しみに！
それでは、みなさん良いお年をー
2023年の振り返りと2024年の目標


## はじめに
インティメート・マージャーでCTOをやらせて頂いてる木村です。

今年もあっという間に過ぎ去り、ブラウザの環境変化が激しさを増す2024年の幕開けが近づいています。
この機会に、今年の振り返りと来年の目標を共有することで自分にプレッシャーをかけるとともに、弊社に興味を持つ方々への情報源になってくれればと思っています。

## 2023年の振り返り

2023年は、開発本部にとって重要なマイルストーンであるGoogle Cloud Platform (GCP) への移行を達成した年でした。創業以来10年間、Amazon Web Services (AWS) を主要なインフラストラクチャとして利用してきましたが、ビジネスの成長とともに、BigQueryや各種AIソリューションのより効率的な利用に対するニーズが高まりました。数ヶ月にわたる一大プロジェクトでしたが（ダブルライトして検証するのは結構大変だった）無事に移行を完了しました!

GCP移行と並行して、DevOpsの領域でも新しい一歩を踏み出しました。ArgoCDの導入は、私たちの継続的デリバリーとオペレーションの自動化を大幅に改善しました。インフラストラクチャとアプリケーションのデプロイメントがより容易になり、リリースサイクルの高速化を実現しました。

また Google Kubernetes Engine (GKE) への移行は、限定公開クラスタを活用したセキュリティの向上とクラウドリソースの管理効率化を実現しました。

これらの施策により、ポストCookieソリューションの導入先が増えたにも関わらず、パフォーマンスの低下を避け、安定してサービスを提供することができました。

## チャレンジと教訓

GCPへの移行は多くのメリットをもたらしましたが、同時にコスト増加のリスクも生じました。実際に取り組んでみないと正確には分からないためです。主要なシステムについては適切に対処できていたものの、予期せぬコストが発生したサブシステムが存在しました。

数値には目を通していたにも関わらず、重要な点を見逃してしまったのは悔しい経験でした。現在このような問題に対処するために、人の目だけに頼るのではなく、ジェネレーティブAIを用いた異常値検知を推進しています。こういった取り組みを増やすことで、運用の効率化と事業継続性の確保を目指しています。

## チームカルチャーと働き方

この数年間に開発に参加してくれたチームメンバーには、次の10年のシステムを支えるコアメンバーとしての役割を担ってくれることを期待しています。そのため、特定の範囲に限定せず、各メンバーが発生する個々の課題を解決する形式を続けてきました。

チームの人数がさらに増加する（例えば、ピザ2枚分を超える規模になる）と、担当領域を明確にし集中しやすい環境にする方が全体としてパフォーマンスが高くなると思いますが、もうしばらくは育成の機会を増やすべく、今のスタイルを続けていく方針です。

正直なところ、担当者の多重化を完全に実現するにはまだ至っていませんが、各メンバーが自身の技術とスキルを磨き、深める機会を提供できたと思います。2024年はこれらの個々の強みを活かしつつ、より効果的なチームワークへの進化を目指します。


## 2024年の目標
私たちのシステムは、システムとビジネスの複雑化に対応するため、単一のシステムに依存するのではなく、複数のシステムを統合して最適化するアプローチを採用しています。
このアプローチにより、外部環境の変化にも柔軟に対応し、全体のパフォーマンスを維持することを目指しています。（アンサンブル学習的なアプローチが大好きです。）

まず、ポストCookieソリューションに関しては、ブラウザ環境の変化に備え、複数のアプローチを開発・検証し続けることが重要です。継続的なパフォーマンスの維持には、施策の数を増やしていくことが鍵となります。

また、2024年にはデータの活用領域を拡大することも重要な目標です。ジェネレーティブAIを利用した取り組みでは、インティメート・マージャーが保有するデータを掛け合わせることで、より効果的な結果を生む事例を蓄積してきました。今後はこれらの取り組みの範囲をさらに広げ、新しいチャレンジへの取り組みを増やしていきます。

## まとめ

振り返ってみれば、2023年は多面的なリファクタリングを行った年でした。攻撃的なデフェンスを意識することでシステムの基盤を整えられました。
2024年はディフェンスをやりきる・最適化していくことも大切ですが、活躍の場を広げること、攻め（オフェンス）のアクションを増やすことに重点を置きたいと思います。

https://qiita.com/advent-calendar/2023/intimatemerger

今年からアドベントカレンダーを開始しましたが、いかがだったでしょうか？

記事を読んで弊社に興味を持ってくれた方は、是非下記よりお気軽にお声がけいただけるとうれしいです！

* Facebook: https://www.facebook.com/kimura.u1/
* X: https://twitter.com/fecker

https://recruit.intimatemerger.com/
TypeScriptでExcludeを利用する

## はじめに
TypeScriptで基本型に対し、一部の型を除外する**Exclude**を紹介します。

## ソースコード
```ts:index.ts
type Person = {
  name: string;
  age: number;
  address: string;
};

// すべてのプロパティのキーをユニオン型として取得
type PersonKeys = keyof Person;

// 'name' を除外したキーのユニオン型を作成
type ExcludeName = Exclude<PersonKeys, 'name'>;

// ExcludeNameに該当するプロパティだけを持つ型を作成
type PersonWithoutName = Pick<Person, ExcludeName>;

const person: PersonWithoutName = {
  age: 30,
  address: '123 Main St',
  // name: 'John', // エラー, 'name' は 'PersonWithoutName' 型に存在しません
};

console.log(person); // { age: 30, address: '123 Main St' }

```
:::note info
personはnameを除外されているので、値を渡すとその時点でエラーがおきます。
:::


```shell:実行結果
~/develop/react/typescript_node$ ts-node index.ts 
{ age: 30, address: '123 Main St' }
```
XshellでJump Hostを使ってIPアドレス制限を回避する

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

SSH接続を使ってサーバー管理することはよくありますよね。
そいでもって、クラウドとかだとソースIP制限で特定のIPアドレスからしか接続できなかったりすることもよくあります。会社の固定IPアドレスからしか接続できないサーバーなんてのもあったりします。

それをXshellのJump Host機能を使ってゴネゴネするという話です。

# 1. Xshellとは？

韓国のNetSarang Computerが製造/販売しているSSHターミナルエミュレータです。

XSHELL - The Industry's Most Powerful SSH Client
https://www.netsarang.com/en/xshell/

画面分割できるSSHターミナルエミュレータがほしくてバージョン5辺りからずっと使っています。

# 2. Jumpホストとは？

SSH接続するときに特定のサーバーを経由して接続するための踏み台サーバーのことです。
Xshellのバージョン7から実装されました。サーバーに接続に行くときに接続します。
以下のようにSOCK5やSSH_PASSTHROUGHなどもあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/3f2dcb90-8f41-6509-12ad-2973f8ca16f7.png)

# 3. 使い方

Jumpホストとしてネットワーク的に接続できるサーバーを指定しておきます。
後は、SSHセッション設定で「プロキシ」＞「プロキシサーバー」を選択するだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/082f293f-a6e5-efbb-287a-576d274b3182.png)

# 4. まとめ

快適なSSHライフをお過ごしください。
投稿アプリ詳細表示機能 同じコードをまとめる


今回もテックキャンプのカリキュラムの復習です！


### 目的
- showアクションの処理の理解
- before_actionを理解

### showアクションのルーティングを設定
詳細画面のパスは、削除や編集と同じくツイートごとに管理
idが1のツイート詳細画面は、`/tweets/1`パス

config/routes.rb
```ruby
resources :tweets, only: [:show]
```

### もし、７つのアクションがある場合
```ruby
変更前
resources :tweets, only: [:index, :new, :create, :destroy, :edit, :update, :show]
変更後
resources :tweets
```

rails routesを実行
ターミナル
```weet GET /tweets/:id(.:format) tweets#show```

### 詳細ボタンを投稿一覧に追加
app/views/tweets/index.html.erb
```ruby
<%= link_to '詳細'、tweet_path(tweet.id) %>
```

### showアクションをコントローラーに定義
- データベースから所得するため
showアクションでは、詳細を表示したいツイートの情報をビューに受け渡すだけ
controllers/tweets_controller.rb
```ruby
  def show
    @tweet = Tweet.find(params[:id])
  end
```
 `app/views/tweets` ディレクトリの中に `show.html.erb`作成

app/views/tweets/show.html.erb
```ruby
<div class="contents row">
  <div class="content_post" style="background-image: url(<%= @tweet.image %>);">
    <div class="more">
      <span><%= image_tag 'arrow_top.png' %></span>
      <ul class="more_list">
        <li>
          <%= link_to '編集', edit_tweet_path(@tweet.id) %>
        </li>
        <li>
          <%= link_to '削除', tweet_path(@tweet.id), data: { turbo_method: :delete } %>
        </li>
      </ul>
    </div>
    <p><%= @tweet.text %></p>
    <span class="name"><%= @tweet.name %>
    </span>
  </div>
</div>
```
ツイートが１つしか表示されないような画面に遷移される
URLにtweetのidに含まれる


### 同じコードをメソッドにまとめる
#### before_actionメソッド
コントローラーで定義されたアクションが実行される前に、共通の処理を行うことができる

例）
`before_action :処理させたいメソッド名`

#### onlyオプション
resourcesと同様に `only` や `except`などのアプションを使用することによって、
_*どのアクションの実行前に、処理を実行させるか*_ などの制限が可能

app/controllers/tweets_controller.rb
```ruby
class TweetsController < ApplicationController
    before_action set_tweet, only: [:edit, :show]
```
この記述により
edit,showアクションが実行される前に、set_tweetに定義されている処理が実行されるようになる
【Python基礎】for文を使った繰り返し処理

for文とは、繰り返し処理に使用する構文のことです。

```書き方
for 変数 in リスト:
    処理
```

# 記載例
```python
hoge_list = [1, 2, 3]
for i in hoge_list:
    print(i)
    
> 1
> 2
> 3
```
　
* 繰り返し処理時、インデックス番号を取得
 ```python
 hoge_list = ["A", "B", "C"]
# 「1」の部分に記載した数からカウントされる（記載しない場合、0から）
# countにインデックス番号、iに要素が入る
for count, i in enumerate(hoge_list, 1):
    print(f"{count}番目: {i}")

> 1番目: A
> 2番目: B
> 3番目: C
```
　
* 次の要素にスキップする場合
```python
hoge_list = [1, 2, 3]
for i in hoge_list:
    if i == 2:
        continue
    print(i)
    
> 1
> 3
``` 
　
* 繰り返し処理を中断する
```python
hoge_list = [1, 2, 3]
for i in hoge_list:
    if i == 2:
        break
    print(i)
    
> 1
```
【Python基礎】if文を使った条件分岐

if文とは、条件分岐に使用する構文のことです。
例）○○の場合、△△である。

```書き方
if 条件A:
    処理A
elif 条件B:
    処理B
else:
    処理C
```

# 記載例
* str型の場合
```python
city = "東京"
if city == "東京":
    print("東京に住んでいます")
elif city == "大阪":
    print("大阪に住んでいます")
else:
    print("東京・大阪ではない場所にに住んでいます")

> 東京に住んでいます
```
　
* bool型の場合
「if flag:」でTrue、「if not flag:」でFalseを表すことができる。
 ```python
flag: bool = False
if flag:
    print("True")
else:
    print("False")

> False
```
　
* int型の場合
```python
age: int = 25
if age < 20:
    print("20歳未満です")
else:
    print("20歳以上です")

> 20歳以上です
```
※「if not age:」とした場合、Noneや空文字だけでなく0も含まれる
　
* AかつBの場合
```python
x: int = 120
if x >= 100 and x < 200:
    print("100番台です")

> 100番台です
```
　
 * AまたはBの場合
```python
x: str = "日曜日"
if x = "土曜日" or x = "日曜日":
    print("今日は休日です")

> 今日は休日です

# このように記載することもできる
if x in ["土曜日" , "日曜日"]:
    print("今日は休日です")

> 今日は休日です
```
　
 *変数に設定する場合
 ```python
 x = "日曜日"
result: str = "日曜日です" if x = "日曜日" else "日曜日ではありません"

> 日曜日です
```
 ```python
 x = None
result: str = x or "日曜日以外"

> 日曜日以外

 x = "日曜日"
result: str = x or "日曜日以外"

> 日曜日
```
軽深演習 # 23 変わる

### 軽深（かるしん　なんちゃって圏論） Advent Calendar 2023 23日目の記事です。

演習形式をとっているので、ぜひ　回答を試みてください。

### 前提知識　変わる
変わることが重要だ。変えることが重要だ。とよく言われます。変わるって一体どんなことなんでしょうか？それほどよくわかってるんでしょうか？　軽深（かるしん　なんちゃって圏論）的ではありますが、考察してみます。
変わらないって、実際は変わらないように日常を作り直してるんではないかとは思えませんか？　50年ほど前、高校生であった私はそんな疑問を持ちました。

図式では恒等射みたいにも思えますね。
```mermaid
flowchart LR
A[変わらない]-->A
```

```mermaid
flowchart LR
A[毎日]-->B[同じ日常]-->B
```
[軽深演習 #7 何もしない](https://qiita.com/zanjibar/items/8221577807d2d525beda)で書いたように、なにもしないと決めることも大切です。そして、かえないと毎日決めることも多くの場合、正しいことです。変えないためには実はかなりの努力を払っているのかもしれません。恒等射は、すごく努力して何もしない状態を作り出しているとすると想像すると、なんだかとても重要な射だと思いませんか？　数学理論的には恒等射は、逆射との関係があるので非常に重要です。

外部要因である黒船到来で変わるのが、多くの場合きっかけでしょう。

```mermaid
flowchart LR
A[黒船]-->B[変わる]
```

でも、自発的、意識的に判断して、行動するのが大切でしょう。黒船はやって来ないかもしれません。変化を本当に起こしたいなら、自分から起こすのが最も近道で確実です。
```mermaid
flowchart LR
A-->B[自発的]-->C
A[黒船なくても]-->D[意識的]-->C[変わる]
```

[軽深演習 #17 会話](https://qiita.com/zanjibar/items/693891e33586108b4beb)に書いたように、自分からはじめることにはどんなことがあるでしょうか？　私は散歩している犬に自分から挨拶するようにしています。人に対して挨拶するのは、心理的に負荷のかかる行動ですが、犬だと気軽です。近所の人と会話が自然にはじまり、日常生活が少し豊かに変わりました。日常で気軽に変えられることからはじめてみませんか？

### 演習 日常生活を変えることで、自分から簡単にできることにはどんなことがあるでしょうか？　犬に挨拶するように気軽なことで結構です。

矢印で考えるだけで、何かが変わってきた気がしませんか？　内容はなんでもいいというグロタンディークの言葉には重みがあると私は思うようになったのですが、みなさんはどうでしょうか？
Qiiagt AdventCalendar 2023 を完走した感想

### 感想と振り返り

https://qiita.com/advent-calendar/2023/rurucun

1人AdventCalendarを作成し、なんとか1人で25日間を完走することができました。

日頃の開発での困りごとをZennのScrapや、Obsdianなどに書くようにしていたのですが、記事としてがっつり1ヶ月25本書き続けたのは今回が始めてだったので大変でした...

記事のタグ内訳としては、下記のような形でした。
(Qiitaプロフィールから抜粋)

ジャンル | 割合
--- | --- 
cloudflare | 21%
expo | 21%
reactnative | 17%
Remix | 17%
bot | 13%

目視で分けた記事の分類では、以下のような形になりました。

ジャンル | 記事数
--- | --- 
入門 | 13記事
Tips | 4記事
Bot | 3記事
AI | 2記事
スクレイピング | 2記事


入門記事が書きやすかったので、入門記事に頼り切りな形になってしまいました。

ただ、Hono/Remix/Cloudflareなど、自分が気になっていた技術スタックを幅広く触れるきっかけになったので良かったです。
年末年始はこれらの技術を使って、新しいサイトやサービスをガンガン高速に立ち上げていきたいと思います。

### 反省

今回記事を書くにあたって特に準備せず、思いつくままQiitaのエディタに書き綴っていたのですが、TextLintやVSCodeなど、快適な執筆体制を整えておいたほうが良かったかなと思いました。

https://zenn.dev/negokaz/articles/aa4e12b76d516597a00e

[QiitaCLI](https://blog.qiita.com/release-qiita-cli-general/)と[ZennCLI](https://zenn.dev/zenn/articles/instal-zenn-cli)を両方使って、両方に記事を出すなどしても良かったかもなと思いました。

https://qiita.com/shogo_wada_pro/items/c41d4a6a9b2b2394e407


日頃からもっとインプットとアウトプットのループを継続しておいたほうが良いなと思いました。

[アウトプット大全](https://amzn.to/3NEp4LH)



### 最後に
2023年 AdventCalendar お疲れ様でした！

拙い記事が多かったですが、ストックやいいねなどがありモチベーションの維持にも繋がりました、ありが
とうございます。
初学者の方が入門する際に、少しでも力に慣れていると嬉しいなと思います。

2024年は更にインプットとアウトプットを回して開発していきたいと思います！
みなさん、良いお年を！
[Nextjs]データを表形式で表示する方法！[DataGrid]

## 初めに
前回は、SQLiteDBからデータを取ってきて、表示する方法を紹介しました！
今回は、Material-UIのDataGridを活用し、見やすく表示する方法を紹介します！
以下の「nihongo.db」データベースの「nihongo」テーブルの情報を取ってきて、表示する手順を具体的に紹介します！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570986/decdce97-a428-0576-950f-ceb5a0118767.png)

# 1. Material-UIのDataGridを導入する
初めに、Material-UIのDataGridをインストールします。
以下のコマンドを使用して、必要なパッケージをインストールします。
```bash
npm install @mui/x-data-grid   # Material-UIのデータグリッドコンポーネント
npm install @emotion/react    # EmotionライブラリのReactバインディング
npm install @emotion/styled   # Emotionライブラリのスタイリング用ツール
```
# 2. 実施例
以下のコードは、インストールしたDataGridを用いて見やすく表示しています。
getAllNihongoData関数にてSQLiteDBからデータを取得し、表示しています。

```typescript
// pages/index.js
import React from 'react';
import { getAllNihongoData } from './api/db';
import { DataGrid } from '@mui/x-data-grid';

const columns = [
  { field: 'id', headerName: 'ID', width: 70 },
  { field: 'aiueo', headerName: 'Visitor Name', width: 150 },
];

const HomePage = ({ data }) => {
  return (
    <div>
      <h1>Next.js SSR with SQLite</h1>
      <div style={{ height: 250, width: '80%' }}>
        // ここでDataGridコンポーネントを挿入！
        <DataGrid 
          rows={data}               // 表示するデータを指定
          columns={columns}         // 表示するカラム情報を指定
          pageSize={5}              // 1ページあたりの表示行数を指定
          checkboxSelection         // チェックボックスの列を有効にする
        />
      </div>
    </div>
  );
};

export async function getServerSideProps() {
  const data = await getAllNihongoData();

  return {
    props: { data },
  };
}

export default HomePage;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570986/7edcd848-0f1d-cf8b-0341-1c688739b316.png)



## まとめ
以上により、DataGridを使用して見やすくデータを表示できました！
表の調節や、表示するデータの数も調節可能なので、試してみてください！
GitHubのブランチ状況が目でわかる！！

# Git Graph

VScodeの拡張機能「**Git Graph**」について紹介させていただきます。

**・視覚的にGitHubのブランチやコミットの状況を把握することができます。**

**・ブランチ名のところをクリックするとそのブランチに行けるよ。**

**・またファイル名をクリックすると、現在のファイルとの差分が見れるゾ。**

あとは実際に触って確かめやがれ。

参考画像
![スクリーンショット (59).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658444/e1be9558-74a7-1f57-d831-05b1346b2f75.png)

GitHubが分かりやすく簡単に使えるようになります。GitHub初心者などにおすすめです。
くそ記事でごめんなさい　m(´・ω・｀)m
Hút mỡ không phẫu thuật công nghệ vaser lipo | Làm đẹp cũng Bác sĩ Võ Thanh Sang

Công nghệ Vaser Lipo (Vibration Amplification of Sound Energy at Resonance) là một phương pháp tiên tiến trong lĩnh vực thẩm mỹ và phẫu thuật thẩm mỹ. Dưới đây là một số lý do mà [ bác sĩ Võ Thanh Sang ](https://www.vothanhsang.com/2023/11/gioi-thieu-vo-thanh-sang.html) khuyến khích bạn sử dụng công nghệ Vaser Lipo khi đến hút mỡ.

![z4988160513923_31b629ee2288de4dcab0602c3d074abc.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661396/cc74d095-b68b-1ec5-8d55-67bc32228238.jpeg)


Bác sĩ Võ Thanh Sang sẽ tiêm dung dịch chứa nước biển pha loãng và thuốc gây tê vào vùng cần điều trị [hút mỡ không phẫu thuật](![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661396/5edbfc70-6fb7-75a3-5df4-801930c8b1ee.png)
http://www.hutmokhongphauthuat.com.vn/


Một thiết bị sóng siêu âm (Vaser) sẽ được đưa vào vùng cần giảm mỡ, phát sóng để tạo sóng siêu âm.

Sóng siêu âm sẽ phá hủy tế bào mỡ tại vùng bụng hoặc bắp tay và biến mỡ thừa cứng đầu thành dung dịch lỏng.

Bác sĩ sử dụng một ống hút nhỏ để loại bỏ dung dịch mỡ từ cơ thể.
![z4979586634766_7e5c6639b6bdc8070ec73ac0cd05878a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661396/f771dbcc-8f96-19ce-9b95-60652f25ca0e.jpeg)
![z4979586643645_69eb414e0fdfac3555b7ff047db1ec1e (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661396/0a98576a-2fae-4400-b296-b5199506383c.jpeg)
バッチ管理システムについての話

## 前書き
バッチ管理システムは、コンピューターシステム上で定期的に実行される自動化された処理を効果的に計画、実行、監視するためのソフトウェアツールやシステムのことを指します。

## バッチ管理システム設計
バッチ管理システムを設計する際には、０から構築する場合も、サードパーティの製品を使用する場合も、いくつかの原則が存在します。

- **ジョブ管理**
    - ジョブ実行のタイミングを制御しなければならないです。

- **エラーハンドリング**
   - `エラー通知`、ジョブ失敗した場合の通知機能。
   - `ロギング`、失敗成功にかかわらず、実行情報の保管が必要。

- **リトライ**
    - バッチ実行に失敗した場合、リトライできなければなりまん。自動、もしくは手動でリトライできる必要があります。

- **依存関係の制御**
    - バッチの間に依存関係存在していれば、それを制御可能にする、実行時間をずらすだけではアンチパタンになリます。

## 技術選定


最初のバッチ管理システムとして、cronを採用することは少なくありません。
> cronは、Unix系オペレーティングシステムのジョブ管理ツールである。

cronは手軽で実装しやすいですが、管理が難しく、エラーハンドリングやリトライの実装には一手間かかります。

cronが限界に達すると、サードパーティのジョブ管理システムを導入することもあります。
周りではrundeckがよく使われます。ただし、それを導入しても、全ての問題が解決されるわけではありません。システムが動いているサーバーの管理が課題になります。
また、継続的に蓄積されるログの管理も必要です。これらの課題が残ります。

コンテナオートスケールサービスを使用したジョブ管理システム、例えば、`ECS Scheduled Tasks`、`EKS CronJob`も存在します。
マネージドサービスではないものの、AWSやその他のクラウドサービスの機能を巧みに活用することで、柔軟性の高いバッチ管理システムを構築できます。
ただし、実装者の技術力に依存するため、サードパーティサービスと比較して一長一短があります。


## 最後に
そのため、`cron`、 `ECS Scheduled Tasks`、 `EKS CronJob`、　`rundeck`など、要件に応じて適切に設計・実装されていれば、これらはすべてバッチ管理システムと見なせると考えています。
Juliaで画像処理（グレースケール化）

# はじめに
Juliaで画像処理したくてOpenCVが使えることがわかり、試したためまとめます。
ついでに別の方法もあったので併せて紹介します。

# OpenCV
まずはOpenCVのパッケージがすでに存在するということで、パッケージを追加。
```julia
using Pkg
Pkg.add("OpenCV")
```

それではコードを書いていきます。
```julia
using OpenCV, ImageView

function image_convert_gray(file_path, save_path)
    img = OpenCV.imread(file_path)

    gray_img = OpenCV.cvtColor(img, OpenCV.COLOR_BGR2GRAY)
    
end

image_convert_gray("test.png", "gray.png")
```
めっちゃOpenCV感ありますね！
ただし、OpenCVで画像を読み込んだ際に、Pythonでは画像が表示されてたと思うんですが、Juliaではピクセルデータで表示されます(関数を作成した場合は表示されません)。
まあ、しっかりグレースケール化して保存はできます！

# Images
もう一つの方法は`Images`というパッケージを用いるやり方です。
下記のパッケージを追加しておきます。
```julia
Pkg.add("Images")
Pkg.add("ImageMagick")
```

それではコードを書いていきましょう。
```julia
using images, ImageMagick

function image_convert_gray(file_path, save_path)
    img = load(file_image)
    gray_img = Gray.(img)
    save(save_path, gray_img)
end

image_convert_gray("test.png", "gray.png")
```
割とわかりやすいですね。
`Gray`は単一のデータに対して変換を行います。読み込んだ画像は複数のピクセルデータから成るので、ブロードキャスト(`.`)を用いて、配列の各要素に関数を適用させる必要があります(`Gray.(img)`)。
Julia感あって個人的にはこちらの方が好きです。

# 結果
![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524375/395a79ac-db43-cce8-467b-debaf743da4c.png)


![gray.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524375/aaf08062-7bca-2f36-ffe8-eb8bffc5d75b.png)

できてますね～。

# まとめ
今回はグレースケール化をしてみましたが、画像処理にはいろいろな処理があります。
OpenCVでやるのが楽なのか、その他の方法でやるのが楽なのかはまだわかりませんが、ケースバイケースで使っていけるようになりたいですね。
それでは！！！
LeetCodeで非同期処理をマスターするぞ！（第1弾）

# 概要
この記事は、LeetCodeの[30 Days of JavaScript](https://leetcode.com/studyplan/30-days-of-javascript/)のPromises and Time（全8問）を1問ずつ解いて
非同期処理をマスターするシリーズの第1弾です。

# 問題：2723. Add Two Promise
[2723. Add Two Promises](https://leetcode.com/problems/add-two-promises/?envType=study-plan-v2&envId=30-days-of-javascript)
```Given two promises promise1 and promise2, return a new promise. promise1 and promise2 will both resolve with a number. The returned promise should resolve with the sum of the two numbers.
 
Example 1:

Input: 
promise1 = new Promise(resolve => setTimeout(() => resolve(2), 20)), 
promise2 = new Promise(resolve => setTimeout(() => resolve(5), 60))
Output: 7
Explanation: The two input promises resolve with the values of 2 and 5 respectively. The returned promise should resolve with a value of 2 + 5 = 7. The time the returned promise resolves is not judged for this problem.

Example 2:

Input: 
promise1 = new Promise(resolve => setTimeout(() => resolve(10), 50)), 
promise2 = new Promise(resolve => setTimeout(() => resolve(-12), 30))
Output: -2
Explanation: The two input promises resolve with the values of 10 and -12 respectively. The returned promise should resolve with a value of 10 + -12 = -2.
 

Constraints:

promise1 and promise2 are promises that resolve with a number
```

つまり、2つの Promise1 と Promise2 があるとき、新しい Promise を2つの数値の合計で返す問題。

**例1**
入力：
　promise1 = new Promise(resolve => setTimeout(() => resolve(2), 20)), 
　promise2 = new Promise(resolve => setTimeout(() => resolve(5), 60))

出力：7
解説：promise1のresolve(2)とpromise2のresolve(5)を合計すると7になる(2+5)
※この問題では、返された Promise が解決する時間は判断されませんとの記載があるので考慮しません。


# 必要な知識
 - 非同期処理のawait
 - Promise.all

# 実装例

**パターン1**
Runtime：53ms
Memory：42.89MB
```
type P = Promise<number>

async function addTwoPromises(promise1: P, promise2: P): P {
  return await promise1 + await promise2
};
```
awaitキーワードを使用して、それぞれのPromiseの結果を個別に持ち合わせて計算します。

<br>

**パターン2**
Runtime：70ms
Memory：42.96MB
```
type P = Promise<number>

async function addTwoPromises(promise1: P, promise2: P): P {
  return new Promise<number>((resolve, reject) => {
        Promise.all([promise1, promise2])
            .then(([result1, result2]) => {
                const sum = result1 + result2;
                resolve(sum);
            })
            .catch(reject);
    });
};
 ```
Promise.allメソッドにより、引数で与えられた2つのPromiseオブジェクトが両方とも完了するまで待ちます。両方のPromiseが完了した場合、その結果を配列として受け取ることができます。
また、その後配列の要素を足し合わせ、その結果をresolveメソッドで返します。もしPromiseのいずれかがエラーとなった場合は、エラーをrejectメソッドで返します。

## ポイント

**パターン1**
awaitキーワードを使用して、それぞれのPromiseの結果を個別に待ち合わせてから合計を計算しているため、返り値はPromiseではなく、計算結果そのものとなります。

**パターン2**
Promise.allメソッドを使用して、2つのPromiseの結果を待ち合わせてから合計を計算しているため、結果は新しいPromiseとして返されます。
新しいPromiseとして返すということなので、こちらの方が問題文の答えとして適切かもしれません。

# 参考
[サバイバルTypeScript Promise](https://typescriptbook.jp/reference/asynchronous/promise#%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E9%9D%9E%E5%90%8C%E6%9C%9F%E5%87%A6%E7%90%86%E3%81%AE%E7%B5%90%E6%9E%9C%E3%82%92%E5%BE%85%E3%81%A1%E5%8F%97%E3%81%91%E3%82%8B---promiseall)
SwiftDataでiCloud同期をさせない方法


Modelのインスタンスを作成して自動iCloud同期をオプトアウトし、cloudパラメータにnoneを明示的に渡します。

```Swift
let config = ModelConfiguration(cloudKitDatabase: .none)
let modelContainer = try ModelContainer(for: Trip.self, Accommodation.self,
                                        configurations: config)
```
JSON配列のキーの重複をチェックし、古いデータの方を削除する


といった処理をしたかったのですが、こういったアルゴリズムっぽい話はChatGPTに聞くと割と一発でした。

## やりたいこと

このようなデータがあり、groupIdが複数あった際にendDateが最新の方を残して古い方は削除したいです。

```js
const data = [
  {
    groupId: 'po',
    classId: 'PO09',
    // その他のプロパティ...
    endDate: '2024-03-16'
  },
  {
    groupId: 'pds',
    classId: 'PDS06',
    // その他のプロパティ...
    endDate: '2024-01-20'
  },
  {
    groupId: 'po',
    classId: 'PO08',
    // その他のプロパティ...
    endDate: '2023-09-23'
  }
];
```

↑これを↓こうしたい

```js
const data = [
  {
    groupId: 'po',
    classId: 'PO09',
    // その他のプロパティ...
    endDate: '2024-03-16'
  },
  {
    groupId: 'pds',
    classId: 'PDS06',
    // その他のプロパティ...
    endDate: '2024-01-20'
  }
];
```

## 以下のコードでできた

GPTさまさまです。

```js
const data = [
  {
    groupId: 'po',
    classId: 'PO09',
    // その他のプロパティ...
    endDate: '2024-03-16'
  },
  {
    groupId: 'pds',
    classId: 'PDS06',
    // その他のプロパティ...
    endDate: '2024-01-20'
  },
  {
    groupId: 'po',
    classId: 'PO08',
    // その他のプロパティ...
    endDate: '2023-09-23'
  }
];

const result = Object.values(data.reduce((acc, item) => {
  const existingItem = acc[item.groupId];
  if (!existingItem || new Date(item.endDate) > new Date(existingItem.endDate)) {
    acc[item.groupId] = item;
  }
  return acc;
}, {}));

console.log(result);

```

## 解説ぽいもの (GPTくん)

GPT解説です。

> ここでの主なタスクは、重複する groupId を持つ要素を特定し、それらの中から最新の endDate を持つ要素を選択することです。これを実現するために、Array.prototype.reduce メソッドを使用します。
> reduce メソッドは配列の各要素に対して指定したリデューサー（コールバック関数）を実行し、単一の出力値（この場合はオブジェクト）を生成します。
このメソッドは2つのパラメータを取ります：リデューサー関数と初期値（ここでは空のオブジェクト {}）。

```js
const result = Object.values(data.reduce((acc, item) => {
  // リデューサー関数のロジック
}, {}));
```


> リデューサー関数は、現在の要素（item）と累積値（acc）をパラメータとして受け取ります。
累積値 acc は、処理中に groupId をキーとして最新の要素を格納するオブジェクトです。
各ステップで、現在の要素の groupId が acc 内にすでに存在するかどうかをチェックします。存在する場合、その endDate と比較して、より新しい endDate を持つ要素を acc に保持します。
存在しない場合、現在の要素を acc に追加します。
> reduce メソッドの実行後、acc には重複なしの groupId をキーとして、それぞれのグループの最新の要素が格納されています。
最終的に、Object.values() メソッドを使用して、acc オブジェクトの値のみを含む配列を取得し、これが最終結果となります。

```js
const existingItem = acc[item.groupId];
if (!existingItem || new Date(item.endDate) > new Date(existingItem.endDate)) {
  acc[item.groupId] = item;
}
```

割とほかでも使えそうですね。
Gatsby.jsとは？Windowsで技術ブログ兼ポートフォリオを作ろう （概要編 ＋環境構築）

# はじめに
こんにちは。えか太郎と言うものです。今回は静的サイトジェネレーター（SSG）であるGatsby.jsを使ってポートフォリオ兼技術ブログを作る話です。今回は概要とSSGとは？などといった概念から書いていきます。ちなみにGatsbyってなんて読むんですかね？読み方分からない人でもわかるようにかけるように頑張ります。
### 追記
主に公式の英語ドキュメントを参考に書きました。本記事だけで分からない部分がある場合は各自参照してください。英検2級程度の私でも理解できたのでそこまで難しくはないとおもいます。

https://www.gatsbyjs.com/docs/tutorial/getting-started/

# Gatsby.jsとは？

Gatsby, Inc.が開発しているJavaScriptによるWebアプリケーションフレームワークです。オープンソースなので無料で使うことができます。また、多くのプラグインが開発されており、マークダウンだけではなくWordPressなどとも併せて使用が可能です。
## なにができるのか？
端的に表すならば静的サイトジェネレーター（SSG）というべきでしょう。静的サイトジェネレーターについては以下の記事のほうがわかりやすかったので参照することを推奨します。

https://qiita.com/manabito76/items/fe91eefe11a74dcf5126
簡潔に言うとAPIだとか外部URLの画像とかをすべて取り込んだ静的なHTML（CSSなど含む）を生成してくれるツールというだけです。
主なメリットは高速化。これ以上はしらなくても困らないでしょう。

ちなみにQiitaで記事を書くときに使うマークダウン形式もGatsbyでは使うことができます。
# 前提条件
この記事を書く上で以下のことはできるものとして気にせず書きます。あしからず。わたしはWindowsでやりますがLinuxでもMacOSでもできたはずです。以下の記事が参考になるかもしれません。
MacOS環境で構築している記事

https://reffect.co.jp/react/gatsby-basic-tutorial-for-beginners#GatsbyJS

## 動作環境
* Windows 10 pro
* ThinkPad（みんなも買おう）
* Celeron + RAM 12GB 
* Node.js（v20.10.0）
* git version 2.43.0.windows.1

Node.jsとGitは必須なのでインストールしておいてください。GitDeskTopでできるかは検証していません。公式ドキュメントにはなかった（多分）

https://nodejs.org/en/

無難にLTS版でいいとおもいます。(私はv20.10.0）
## あったほうが良い知識
* HTML、CSS、JavaScript（基礎程度）
* コマンドラインの操作
* Node.js
* GitHub及びGitコマンド
* お好みのエディタ。私はVScode使います
# 環境構築
以上の前提条件（nodeやgit）の用意ができたら次にお進みください。
### Gatsby-CLIのインストール
GatsbyはCLIを使用して操作します。ただしnpmパッケージとして提供されているんのでnpmコマンドですぐにインストールできます。ターミナルで以下のコマンドを入力してインストールしてください。インストールできないときはNodejsが正しくインストールできているか確認してください。
### 
~~~
npm install -g gatsby-cli
~~~
バージョンの確認
~~~
gatsby --version
~~~
わたしはGatsby CLI version: 5.13.1がインストールされました。

## 使用状況のデータの収集について
初めてインストールしたときには匿名の使用状況のデータを収集することを通知するメッセージが表示されます。以下のコマンドを入力すれば収集を拒否または同意することができます。
~~~
無効化 gatsby telemetry --disable
有効化 gatsby telemetry --enable

~~~
# おわりに
続編もあります。続編では実際に簡単なホームページを作成します。ぜひ御覧ください。
APIの種類と違い

## 初めに
一言にAPIといってもいくつかの種類があります。今回はその私の調べた様々な種類のAPIについて簡単に具体例も挙げて紹介していこうと思います。

## WEB API
WEB APIとは大まかにいうとWebにてAPIを利用できるようにしたものです。このWEB APIの代表例としましてはオンラインショッピングやXが挙げられます。

## ネイティブAPI
ネイティブAPIとはあらかじめOSに組み込まれており、ハードウェア制御やメモリの操作を実行するようです。皆さんも一度は聞いたことのあるマルウェアもこのネイティブAPIの技術を利用して悪事を働くそうです。ネイティブAPIの代表例はWinExec、WriteProcessMemoryなどがあります。

## ランタイムAPI
ランタイムAPIはContextを利用し、アプリケーション実行のためのリソース設定と制御をする際に使用します。代表例はJavaScript、Ruby on Rails APIなどが挙げられます。

## データベースAPI
アプリケーションからデータベースのシステムリソースにアクセスするためのインターフェースといった感じです。代表例はOCL API、ODBC APIなどが挙げられます。

## まとめ
以上が私の調べた様々なAPIの簡単な説明と具体例のまとめです。特に調べた中でWeb APIやネイティブAPIに興味が湧きました。Web APIに関してはこの技術を使用している具体例が多く上記で紹介したAPIの中でも一番身近に感じました。ネイティブAPIに関しましてはマルウェアにも使用されるということで今後の私がセキュリティインシデントに巻き込まれないためにもその手法などを学んでみたいと思います。

## 参考にさせていただいたサイト
https://www.ashisuto.co.jp/eai_blog/article/201712_eai_webapi.html
以前投稿していたコードに関してAI（GPT-4 Turbo）に聞いてみた結果


https://qiita.com/4q_sano/items/bf92f4ebf06d6bb1ead3

以前(2021年08月31日)、投稿した↑こちらの記事ですが、今ではAI（GPT-4 Turbo）に以下のように質問するだけで、理想的なコードを教えてくれます。

質問：**「WKWebViewでtarget=“_blank”に対応する方法は？」**
AI：　リンクを現在のwebViewでロードするコードを作成

質問：**「これをsafariで開くようにして」**
AI：　リンクをSafariで開らくコードを作成


:::note info
>navigationTypeが.linkActivated（ユーザーがリンクをタップした）である場合、そしてtargetFrameがnilまたはメインフレームではない（つまりtarget="_blank"で開くリンクである）場合に、URLがSafariで開かれるようになります。 

こちらも配慮もされており、我々が見落としがちな実装もしっかりコーディングされております。
また、コードの解説も丁寧にしてくれます。

```swift:AIが作成したコード
import WebKit
import UIKit

class ViewController: UIViewController, WKNavigationDelegate {

    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.navigationDelegate = self
        view = webView

        let url = URL(string: "あなたのURL")!
        let request = URLRequest(url: url)
        webView.load(request)
    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        if navigationAction.navigationType == .linkActivated, let url = navigationAction.request.url, navigationAction.targetFrame == nil || !navigationAction.targetFrame!.isMainFrame {
            if UIApplication.shared.canOpenURL(url) {
                UIApplication.shared.open(url, options: [:], completionHandler: nil)
                decisionHandler(.cancel)
            } else {
                decisionHandler(.allow)
            }
        } else {
            decisionHandler(.allow)
        } 
    }
}

```
:::

![FireShot Capture 002 - リートン - wrtn.jp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82835/14653fc9-e6b0-0118-60ed-410289c4a358.png)
パッケージやjavaコマンドの基礎知識（Java Silver勉強）

## 最初に
この記事は、以下の書籍を通じてJava silverの合格に向けて自分が学んだ内容を体系的にアウトプットする記事である。（目指せ年内合格！）
[徹底攻略Java SE 11 Silver問題集[1Z0-815]対応](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Java-SE-11-Silver%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-815/dp/4295007625/ref=asc_df_4295007625/?tag=jpgo-22&linkCode=df0&hvadid=342700130622&hvpos=&hvnetw=g&hvrand=9715255718806805548&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009303&hvtargid=pla-830348236008&psc=1&mcid=e12ce628cc5a33b29a77da3a85a6cdf0&th=1&psc=1
)

## 勉強記録
### 1章　簡単なプログラムの生成

- パッケージの目的
    - 名前空間の提供により、名前の衝突を避ける
        - 名前空間？
            - クラスやインターフェース、メソッドなどの名前を一意に識別するための仕組み
    - アクセス修飾子と組み合わせてアクセス防御機能を提供
        - アクセス修飾子？
            - public、protected、privateといった修飾子の総称で、クラスやそのメンバーがどこからアクセス可能であるかを決定
            - https://java-code.jp/134
    - クラスの分類を可能にする

- パッケージ
    - 慣習的に、ドメイン名を逆にした文字列をパッケージ名に利用（一意にするため）
        - 「xxx.co.jp」というドメインなら、「jp.co.xxx」
    - パッケージ宣言を省略したクラスは、デフォルトで無名パッケージに属すると解釈
        - 規模の大きなプログラムに使用されることはまずない
            - https://programmer-life.work/java/package

- java.langパッケージ
    - 基本的なメソッドがまとまる
    - import文不要

- エントリーポイント
    - 処理を始めるためのメソッド（mainメソッド）
    - args以外の部分は変更不可
        ```java
        public static void main(String[] args){
        }
        ```
    - 公開、インスタンス生成不要、戻り値なし、メソッド名はmain、引数はstring配列型がルール
    - 可変長配列でもOK

- javaコマンド
    - JVMを起動するためのコマンド
    - JVMは起動後、指定されたクラスをロードし、mainメソッドを呼び出す
        - 引数（起動パラメータ）が、mainメソッドの引数となる
        ```java
        	java 完全修飾子クラス名　引数1 引数2 ・・・
        ```    
    - javaコマンドで実行できるクラス
        - mainメソッドを持つクラスファイル
        - jarファイル内のメインクラス
            - jarファイルとは？
                - 「Java Archive」ファイルの略称
                - 「アーカイブ」つまりJava開発で利用するファイルをまとめて保管しているファイル
                - 具体的には、jarファイルはコンパイル済みのclassファイルや画像などのファイルを、zip形式に圧縮してまとめたファイル
        - モジュールに含まれるメインクラス
    - javaコマンドは、以下と等しい
        ```java
        javac -d メモリ空間 Sample.java
        java Sample a b c
        ```
    - 起動パラメータ
        - 空白くぎり
        - 空白を含む文字列を渡したい時は、””で囲む
        - “を渡したい時は、¥でエスケープする

## 感想
今更やる意味あるのかと少し疑問もあったが、意外と知らない＆忘れていることが多い。（
いつでも取り出し可能な知識をどれだけ持てているかが生産性の向上に大切と世界一流エンジニア（牛尾さん）も言っていたので、ひきつづきやっていく。
SwiftDataで、保存したはずのデータが勝手に消えてしまうことがある時の解決策？？


アプリでしっかり保存したはずのデータが再起動すると消えているので、なんだこれ？？？となっていました。


簡易的にmodelContainerを作成する場合は、以下のように、オートセーブの設定を変更できますよね。
```Swift
WindowGroup {
    ContentView()
}
.modelContainer(for: User.self, isAutosaveEnabled: false) 
.modelContainer(for: User.self) //指定しない場合のデフォルトはtrueか？
```
しかし、どうやら自作で、Contextを作成した場合は、オートセーブがデフォルトでは無効になっていることがあるようです。


```Swift
let newContext = ModelContext(container)
print(newContext.autosaveEnabled)
newContext.autosaveEnabled = true //明示的に自動保存を有効にする
```

ちなみに私の環境で、一度実行してみたときは最初から、自動保存が有効になっていましたが、たまに保存したはずのデータが消えていたりしたので、もしかしたら、SwiftData様の御気分で変わってしまうのか？？😂こればかりはよくわからないので、一応trueに設定しておいた方がいいかもしれません。

よくわかりません>_<


ちなみに安全策は、try context.save()で明示的に保存することです。面倒ですが、書けば保存はされると思います。


参考

https://www.hackingwithswift.com/quick-start/swiftdata/how-to-enable-or-disable-autosave-for-a-modelcontext


あと、バックグラウンドスレッドの ModelContextも自動では保存してくれないみたいです。
以下参照

https://zenn.dev/yumemi_inc/articles/2a929c839b2000#その他%3A-バックグラウンドスレッドで保存




## ドキュメントにも記載があります。
https://developer.apple.com/documentation/swiftdata/modelcontext/autosaveenabled

デフォルトはfalseだが、mainContextの場合のみtrueになるというなんとも罠な仕様
RailsのCORSで配列の環境変数を使うときの注意

# はじめに
こんにちは、HappyManaです。
RailsのCORS設定で、オリジンを複数指定したいことがあり、環境変数に配列を使いました。
その際の注意点を備忘録として残します。

# 環境変数に配列を使う
環境変数で配列を使う際は、以下のように書きます。
```env
CLIENT_ORIGIN=["http://localhost:8000","https://example.jp"]
```

CORSのoriginsには以下のように書きます。
```
origins JSON.parse(ENV['CLIENT_ORIGIN'] { '[]' })
```

# 注意点
## シングルクォーテーションで囲わない
例として、以下のようにシングルクォーテーショを使った配列にします。
```env
CLIENT_ORIGIN=['http://localhost:8000','https://example.jp']
```

そうすると、以下のエラーが出ます。
```
/usr/local/lib/ruby/3.1.0/json/common.rb:216:in `parse': 451: unexpected token at ''http://localhost:8000','https://example.jp']' (JSON::ParserError)
```

これは、JSON.parseを使った時に、ダブルクォーテーションで囲われていないためにでるエラーです。
そもそもJSONの構文では、ダブルクォーテーションで要素が囲われている必要があります。
https://www.json.org/json-ja.html

JSONの構文としてシングルクォーテーションで囲うとエラーがでるため、ダブルクォーテーションで囲う必要があります。
Architecting Distributed Transactional Applications

『Architecting Distributed Transactional Applications』は、（おそらく）O'Reillyサブスク限定の短いレポートです。

<a href="https://www.oreilly.com/library/view/architecting-distributed-transactional/9781098142643/"><img src="https://learning.oreilly.com/covers/urn:orm:book:9781098142643/400w/" width="200" alt="Architecting Distributed Transactional Applications書影"/></a>

著者ガイ ハリソンさんは、最近だと『CockroachDB: The Definitive Guide』を書かれた方で、20年以上前からデータベース関連の本を何冊も書かれています。
中でもOracleSQLチューニングは、新卒当初めちゃくちゃお世話になった本で、この本のおかげである程度のSQLが付きました。(ちなみに翻訳は、ひがさんだったりします)

<a href="https://www.amazon.co.jp/dp/4894711494"><img src="https://m.media-amazon.com/images/I/51NAMZ32NFL.jpg" width="200" alt="OracleSQLチューニング―オラクルの潜在能力を引き出す実践的チューニングガイド書影"/></a>

## 分散トランザクションアプリケーション

このレポートでは分散トランザクションアプリケーションというお題目ですが、基本的には別々に分散アプリケーションと分散データベースについて語られています。

## 分散アプリケーション

分散アプリケーションは、いわゆるマルチリージョンにデプロイしたアプリケーションを意味し、グローバルロードバランサが、リクエストをリージョン毎のアプリケーションに振り分けるものをさしています。

多くの分散設計では、サービス間の一時的なメッセージはリージョンを跨ぐことはないが、リージョン全体のダウンも考慮して、マルチリージョンでレプリケーションするケースもちらほら見かけるようになった、としています。これは短いレポートなのでこの程度の言及具合ですが、実装のパターンは『Patterns of Distributed Systems』に結構詳しく載っています。

## 分散データベース

まず、CAP定理のトレードオフが変わってきているという話があります。

CAP定理(Brewerの定理)とは、分散システムでは3つの望ましい特性のうち、多くても2つしか持つことができないというものです。

- 一貫性
    すべてのユーザーが同じデータベースの状態を見る。    
- 可用性    
    分散システムのすべての要素に障害が発生しない限り、データベースは利用可能であり続ける。    
- パーティション耐性  
    ネットワークパーティションによって分散システムが2つに分割されたり、ネットワーク上の2つのノードが通信不能になったりしても、システムは動作を継続できる。

以前は、ネットワークパーティションが問題だったので、一貫性を犠牲に、結果整合性を追い求めていました。が、大陸間ネットワークの冗長化によって、その発生確率が下がったので、分散型かつトランザクション一貫性を保証する方向に移行しつつある、というものです。GoogleのSpannerやCockroachDB、YugabyteDBがその代表例である、と。

なので、それらのデータベースではマルチリージョンでレプリケーションし、一貫性のために合意形成メカニズムを使います。ただ、レイテンシーと可用性の間にはトレードオフは残っていて、リージョンの存続が必要な場合、複数のリージョンがトランザクションの合意形成に参加する必要があるため、書き込みレイテンシが増加する、ということがあります。Writeヘビーなアプリケーションはそれを考慮して、結果整合性の方を選択する方がいいかもしれません。インフラ、ミドルウェアレイヤでは可用性+パーティション耐性か、一貫性+パーティション耐性かをプロダクションレディな状態で選択できるようになったので、具体的にどういうユースケースでどちらを選ぶべきかは、今後さらに議論されていくのではないかと思います。
javaのコンパイルと実行方法

# Javaのコンパイルと実行
これから、Javaのソースコードを作成～実行までの流れを紹介します。
（JDKインストール済みでコンソールでJavaが使えるようになっている
 こと前提で話します。）

①ソースファイルの作成
・以下のソースコードをメモ帳（サクラエディタなどのテキストエディタ）を開いて、
　記述する。
~~~
public class Test {
    public static void main (String[] args){
        System.out.print("Hello");
    }   
}
~~~
②ファイルを保存する
・ソースコードが書けたら、ファイルを保存しますが、
　この時に拡張子は（.java）にすること！また、今回はわかりやすいように
 　デスクトップに保存しよう。
  
:::note info
（保存する時、「ファイル名」と「ファイルの種類」を決められるので、
 ここで「ファイル名」は「Test.java」として「ファイルの種類」は
 「すべてのファイル」を選択して保存する。）
:::
③ソースコードをコンパイルする
デスクトップで右クリックをし、「ターミナルで開く」を選択。
ターミナルで以下のコマンドを打ってみよう。
~~~
javac Test.java
~~~
これでコンパイルができ、「Test.class」というファイルができる。

④作ったソースコードを実行する
・③でコマンドを打った後、続けて以下のコマンドを打つ。
~~~
java Test
~~~
これで「Hello」という文字が出たら成功です！
（ソースコードが実行できています。）
JINSがAdvent Calenderに参加してみて

[JINS Advent Calendar](https://qiita.com/advent-calendar/2023/jins)最終日も何度目かの大間がまとめ的な記事を担当します。
## はじめに
12/25でJINSとしてのAdvent Calender、無事やり切ることができました〜
記事書いて欲しいよの依頼に快諾してくださった各メンバには非常に感謝です！
今日はそんなAdvent　Calenderの振り返りを簡単に実施したいと思います。
## ちょっとだけ背景
JINSも社内にIT・デジタル系の人材が少しずつ増えてきており、
* 自身の成長のためにアウトプットをやっていきたい
* 技術を通して社外のエンジニアとの接点を作っていきたい
* 技術観点からJINSを知ってもらいエンジニア採用にもつながる機会になれば

といった観点で、ジンズでもテックブログ的なものを実施できないかという声が一部で出始めていました。
そのような中で
* お祭り的にみんなで楽しく記事を書いてみよー
* 執筆することに慣れてない人も多いから、まずは書くのに慣れていこうー

という点でQiitaのAdvent Calenderをやってみないかという@Takuma_Satoからのアドバイスもあり、私(@tskoma)も企画段階からこの取り組みに参加してみました。
楽しそうだよね！ということで私も企画から参加したものの、当初は正直(私個人としては)「そもそも参加してくれる人がいるだろうか」、「手を上げてくれたもののちゃんと執筆してくれるだろうか」な不安があったのは正直なところでした。
そんな不安はなんのその、最終的には色々な部署から参加してくださり、計16人でAdvent Calender完走することができましたー:clap:
## 実際にやってみて
* タグ別
偏りすぎることはなく、言語の話からネットワークからデータ基盤まである程度幅広く取り上げられたかなと思っています！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618521/eb68877b-6d30-9e9c-c1e0-b35870c84896.png)
(若干クラウド寄りなのは多分私の投稿が多めなため。。。)
* スキルセット別
すごーくざっくり記事を書いてくれた人の人材類型としてはエンジニア系７割、PM系3割といった感じでした。
サービス企画やオフショア開発などなど、特定の技術カットでない話が出てきたところも面白い点かなと思っています。
## 今後
今回このAdvent Calendarというお祭りに乗っかる形で始めたJINSのテックブログ活動ですが、今後も何かしらの形で継続して続けていこうと考えています。
Qiitaで続けるか別のプラットフォームを使うかなどは検討中なのですが、アウトプットしていくこと、社外に継続して発信していくことは続けていきます。
今までの記事を読んできて「なんかJINSって面白そうなことやってるんだな〜」と少しでも感じてくださった方は、時々チェックしてもらえると嬉しいです！
## 最後に
このAdvent Calendarを読んでいただくとわかるように、JINSはフロントエンド/バックエンド/クラウド/ネットワーク/データ/セキュリティ/ハードウェアと色々な技術ネタと、それぞれを担う多種多様なメンバが在籍しています。
少しでもご興味を持ってくださった方はぜひ応募していただければと思います！
[IT・デジタル採用](https://jinsholdings.com/jp/ja/recruit/digital/)
Windows PowerShellでwgetとcurlが動作しない件（Windows 10）

## ことの経緯
　様々な記事やGithubで、当たり前のようにタイトルのようなコマンドを使用しますが、専門ではないため、環境構築が適当すぎたのか動作しませんでした。
 
 　LinuxやMacOSでは当たり前のようにできるようなのですが、私のWindows PowerShellでの実行環境ではそのままでは動作しませんでした。
　備忘録になります。

## 実行環境
- Windows 10 Home, version: 22H2
- Windows PowerShell (Windows Terminal上で実行)

## 解決方法
　何かしらのファイルをダウンロードしたい場合、以下の例の通り`-outfile`と出力先を記載することによって、出力先ファイルを指定する必要があります。
 （`-OutFile`などにしても同様に動作します。）
 （`wget`、`curl`の違いが分かっていませんが、どちらも同様に出力先の指定が必要でした。）
 
```terminal:example
$ wget https://ja.overleaf.com/ -outfile exp.html 
```

　環境によっては動くのかもしれませんが、私の適当な環境では上記の通りにしなければ動作しませんでした。
 　ご参考までに、お試しください。
Google Classroom APIを使う

# Google Classroom APIを使う
GASで使用することが可能です。

## Google Classroom とは
GIGAスクール構想でChromebookが配布された学校などで導入されている、生徒、教師間でクラスをつなぐやつです。課題とかも設定できます。

## Google Classroomで困っていること
* スマホに通知が来ない
学校管轄のアカウントで私的端末にログインしたくないのでスマホに通知が来ません。なのに学校にいない時間にも通知が来るので困ります。
* クラスが多すぎて確認がめんどくさい
数えてみると25のクラスがありました。一つ一つ読み込まなければいけないため非常にめんどくさいです。

課題提出に関しての投稿があったりするので無視できない。

## Google Classroom APIというのがあるぞ!!
Googleが公式で提供しています。
できること
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353450/0fc62beb-6268-ac92-436f-55899580a07c.png)
[Google公式より](https://support.google.com/edu/classroom/answer/6253304)


## クラスの投稿内容を取得してみる
(ご自身の責任でお試しください)
1\. スプレッドシートで新規ファイルを作成
2\. 投稿内容のシートを作成
3\. GASでサービスからGoogle Classroom APIを追加
4\. 以下のコードを実行

``` javascript:getclassroomid.js

function getid() {
  let courses = [];
  let option = {
    pageToken: null,
  };
  while (true) {
    courses = Classroom.Courses.list(option).courses;
    if (!null) {
       break;
    }
  }
  if (courses.length === 0) {
    Logger.log("No courses found.");
  } else {
    Logger.log("Courses:");
    for (course in courses) {
      Logger.log('%s (%s)', courses[course].name, courses[course].id);
    }
  }
}

```
クラスごとのコードが出力されるので投稿を取得したいクラスのコードをコピー

5\. 続いて以下のコードをGASで実行（前のコードはけしてOK）

```javascript:getclassindex.js

function listCoursesAnnouncements() {
 let ss = SpreadsheetApp.getActiveSpreadsheet(); //書き込み先のスプレッドシートファイル
 let sheet = ss.getSheetByName("投稿内容"); //書き込み先のシート

 let classroomid = "{ここに先ほどコピーしたIDをペースト}";
 var aaa = 6 ;
 let courseId = classroomid; // コースIDを記載
 let announcementsList = [];
 try {
   let course = Classroom.Courses.Announcements.list(courseId);
   for(let announcements of course.announcements){
     
     sheet.getRange("B"+ aaa).setValue(announcements.text);
     sheet.getRange("C"+ aaa).setValue(announcements.alternateLink);
     sheet.getRange("D"+ aaa).setValue(announcements.updateTime);
     console.log(announcements)
     var aaa = aaa - 1;
     if(aaa<2){
       break
     }
  }
  } catch (err) {
   Logger.log(err);
  }
}

```
汚いコードでｺﾞﾒﾝ…
### 取得できたはず!!
これができればほかに応用が利く!!
Job Interview Questions Java 3



How do you reverse a string in Java?

How do you swap two numbers without using a third variable in Java?

Write a Java program to check if a vowel is present in a string.

Write a Java program to check if the given number is a prime number.

Write a Java program to print a Fibonacci sequence using recursion.

How do you check if a list of integers contains only odd numbers in Java?

How do you check whether a string is a palindrome in Java?

How do you remove spaces from a string in Java?

How do you remove leading and trailing spaces from a string in Java?

How do you sort an array in Java?

How do you create a deadlock scenario programmatically in Java?

How can you find the factorial of an integer in Java?

How do you reverse a linked list in Java?

How do you implement a binary search in Java?

Write a Java program that illustrates merge sort.

Can you create a pyramid of characters in Java?

Write Java program that checks if two arrays contain the same elements.

How do you get the sum of all elements in an integer array in Java?

How do you find the second largest number in an array in Java?

How do you shuffle an array in Java?

## 参考

https://www.digitalocean.com/community/tutorials/java-programming-interview-questions
Job Interview Questions Java 2


1. What is the difference between JDK, JRE, and JVM?
2. What is the difference between an abstract class and an interface?
3. What are the different access modifiers in Java?
4. What is the difference between a checked and an unchecked exception?
5. What is the difference between a HashMap and a TreeMap?
6. What is the difference between a static and non-static method?
7. What is the difference between a stack and a queue?
8. What is the difference between overloading and overriding?
9. What is the purpose of the 'finally' block in Java?
10. What is a thread in Java? How do you create and start a thread? It is important to note that the interview questions may vary depending on the specific role and project requirements. It is always a good idea to prepare for a variety of questions and be ready to discuss your experience and projects in detail.

2- Difference between local and instance variable.

3- write a code to reverse the string

4- internal working of HashMap

5- What is serialization

6- Explain lambda expression

7- Advantages of springboot

8- Difference between == and . equalsTo

9- Difference between unique key and primary key

10- Difference between method overriding and method overloading with example

11- Types of access specifiers

12- Use of this keyword

13- Explain different springboot annotations

14- Explain exception hierarchy

15- what is index and view

16- difference between extending thread class and runnable interface.

17-why we use static in main method

18- Spring Mvc flow

19- How can we avoid null pointer exception

20- What is session and session factory



Explain the functionality of linked list.

What are the four basic principles of OOPS?

What is inheritance?

What is the way of inheriting variable of one class to any other class?

What is Polymorphism?

What are the different types of inheritance?

What is the difference between classes and interface?

What is software development life-cycle?

What is normalization of databases, joins, and keys?

What are loops?

List different advantages of DBMS

What is Database Management System?

What is database Schema?

What are the conditional statements?

What is the difference between the foreign key and reference key?

The structural difference between bitmap and b-tree index?

What is the difference between a Clustered index and non-clustered index?

Differentiate between socket and session?

What is an array?

Given an array of 1s and 0s arrange the 1s together and 0s together in a single scan of the array. Optimize the boundary conditions.

Define Data Abstraction. What are their importance?

Write a function to swap two numbers without using a temporary variable.

what is virtual function and pure virtual function?

## 参考

https://www.quora.com/What-are-the-common-Java-interview-questions-asked-in-TCS-interview-for-2-year-experienced

https://www.youtube.com/watch?v=LD3YK_r3hpg
Job Interview Questions Java 1


How do you handle exceptions in Java?

What is the difference between an interface and an abstract class in Java?

How do you implement polymorphism in Java?

How do you implement a linked list in Java?

How do you implement a stack in Java using an array?

How do you implement a binary search tree in Java?

How do you implement a bubble sort algorithm in Java?

How do you implement a merge sort algorithm in Java?

What is the Java Virtual Machine (JVM)?

What is the difference between static and non-static methods in Java?

How do you implement inheritance in Java?

How do you implement a queue in Java using an array?

What is the difference between a HashMap and a TreeMap in Java?

## 参考

https://www.btreesystem.com/blog/tcs-java-interview-questions/