OmniAICreator/Qiita-1.07M huggingface dataset:
せんせー、ゲノム編集ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/7f59d21b-0564-377b-a326-47169950dc66.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/319ddbbb-e9dd-5833-688d-5808a705af9b.png)

せんせー、ゲノム編集ってなに？

# ゲノム編集

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/20dff797-0d89-cbac-cdf5-76fe90c321e6.png)

ゲノム編集というのは、生物のDNA（デオキシリボ核酸）という部分を「書き換える」ことを言います。DNAは私たちの体の設計図のようなもので、私たちの目の色や身長、髪の色などを決めています。

それを子供にわかりやすく説明するために、お菓子を作るレシピに例えてみましょう。

例えば、あなたがチョコレートクッキーを焼きたいと思って、レシピを見ました。でも、そのレシピはバニラクッキーのものでした。それでも大丈夫、レシピの中の「バニラ」を「チョコレート」に書き換えることができたら、あなたが焼きたいチョコレートクッキーが作れますよね。

ゲノム編集も同じようなものです。生物のDNAの「レシピ」を少し書き換えることで、新しい特徴を持つ生物を作り出すことができます。例えば、病気になりにくい植物や、さまざまな色の花などを作ることができます。

でも、この「レシピ」を書き換えることは、とても難しいし、それによって予期しないことが起こるかもしれません。だから、ゲノム編集は慎重に行うべきものなんです。

このように、ゲノム編集は生物のDNAの「レシピ」を書き換えて、新しい特徴を持つ生物を作り出す技術のことを言います。

# まとめ

ゲノム編集は生物のDNAの「レシピ」を書き換えて、新しい特徴を持つ生物を作り出す技術のこと
AndroidStudioで新規アプリビルド時エラーが発生（Javaバージョン不整合）

# 直面したこと
自学中に、テンプレートコードをビルドしただけで、以下のエラー発生
[こちら](https://www.fuwamaki.com/article/485)を参照し解決（ありがとうございました。）

選択したテンプレート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518871/255080ab-9f7e-f81f-2001-a8bd23260175.png)


## 環境
* Android Studio Flamingo | 2022.2.1
* Build #AI-222.4459.24.2221.9862592, built on March 31, 2023
* Runtime version: 17.0.6+0-b2043.56-9586694 amd64
* VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
* Windows 11 10.0
* Memory: 1280M
* Cores: 16

## エラー
```compileDebugJavaWithJavac' task (current target is 1.8) and 'kaptGenerateStubsDebugKotlin' task (current target is 17```

## 原因（多分）
おそらく、AndroidStudioで生成したテンプレートコードとAndroidStudioがデフォルトにしているJavaバージョンの不整合

## 対処法
先のリンクを参照し、対応①を実施した。（Version17に合わせる対応）

修正後のキャプチャ（修正前は、Versionが1.8だった、）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518871/5e9a1ead-4f8c-c685-c201-5db2a0fcebc4.png)
せんせー、クリーン電力ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/7f59d21b-0564-377b-a326-47169950dc66.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/319ddbbb-e9dd-5833-688d-5808a705af9b.png)

せんせー、クリーン電力ってなに？

# クリーン電力とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/68a2c297-4c1d-578a-d6e0-4e2a63352211.png)

まず、エネルギーとは何か、ということから始めましょう。エネルギーは、家の電気をつけたり、おもちゃの電池で動かしたり、お車が走るために必要な力のことを指します。そして、このエネルギーを作るためにはいろいろな方法があります。

これまでは、私たちの電気の大部分は石炭やガス、原子力といったものから作られてきました。でも、これらの方法は地球に優しくない方法なんです。石炭やガスを燃やすと、空気が汚れてしまいます。また、原子力は危険で、事故が起こると大変なことになります。

それに対して、「クリーン電力」は、地球に優しい方法で電気を作ることを意味します。太陽からの光や風、水の流れを利用して電気を作り出すのです。これらは、空気を汚さないし、事故の危険もないので、とても安全です。

例えば、太陽からの光は太陽電池で電気に変えることができます。また、風は風車を回して電気を作ることができます。水の流れも同様に、ダムで高いところから水を落とすことで電気を作り出すことができます。

これらの方法で作られる電気は「クリーン電力」で、地球に優しい電力なんです。私たちがこれからの生活を楽しむためにも、地球を守るためにも、クリーン電力を増やしていくことが大切なんですよ。

# まとめ

「クリーン電力」は、地球に優しい方法で電気を作ること
Power BI Tips - Power BI DesktopとMySQLの接続エラーについて

# 概要
中小製造業向けに、簡単に生産進捗を管理できるPIYOT Cloudというサービスを提供していて、
DBにAzure Database for MySQLを使用しています。
Power BI DesktopでDBに接続して分析を行う仕掛けにしてるんですが、
お客様から接続できないという情報を頂いて、少し調べた内容の共有。

:::note info
**2024.12.19 追記**
**最新版のMySQL Connector/NET（バージョン：9.1.0）では現象発生しませんでした！**
:::

# 現象
お客様の環境では、こんなエラーが出たとのこと。
「MySQL.Data.MySqlClient」が見つからない・・・。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/4e89e750-676f-c6ac-672f-34b0e7a021a2.png)

Power BI DesktopからMySQLに接続する際には、
事前に「MySQL Connector/NET」をインストールしておく必要があるのですが、
そのバージョンを確認してもらったら、「8.0.33.1」。

私の環境を確認したら、「8.0.32」。
インストールサイズ、何かおかしい？？？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/e3cdd56e-5c25-1376-917d-ae970a571806.png)

こちらでも「8.0.33.1」をインストールしたら、同じエラーが出ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/3ca25480-18c0-ddcc-a833-3df0e7a8b60a.png)

2023年7月27日現在の最新バージョンは「8.1.0」
試しにこれをインストールするも・・・同じエラー（汗）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/877629ed-787d-f9e8-3403-6b9fe50ca321.png)

# 対策？
というわけで、現状は「8.0.32」をインストールしておくしかなさそう。
なので、バージョン8.0.32の取得手順を記載しておきます。

① [MySQL Connector/NET のダウンロードサイト](https://dev.mysql.com/downloads/connector/net/)にアクセス。

② 表示されたページの「Archives」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/20c24110-e7eb-e85e-ad07-25647bc69957.png)

③ Product Versionを「8.0.32」にして、「Download」ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/034e86b3-fb43-8207-5627-163da0546ccf.png)


8.0.33.1以降、明らかにサイズが違うので、何か不足しているのかな・・・。
（SwiftUI）.sheetの使い分けが難しかった。

# ２種類の.sheet
始めにみなさんご存知かと思われますが、swiftUIでモーダル遷移させるsheetには２種類あります。それが下の２つです。
1...sheet(isPresented:onDismiss:content:)

https://developer.apple.com/documentation/swiftui/view/sheet(ispresented:ondismiss:content:)

2...sheet(item:onDismiss:content:)

https://developer.apple.com/documentation/swiftui/view/sheet(item:ondismiss:content:)

大きな違いは引数が.sheet(isPresented:..)になっているか、それとも.sheet(item:..)になっているかの違いです。「isPresented」はバインディングされたBool値がtrueになることでシートを表示させ、「item」はIdentifiableプロトコルに適合した任意の型が代入されることでシートを表示させます。

# つまずき

自分の理想とする挙動は、動画１のように選択された項目の値を次のViewへ渡し、TextField内で表示させることです。
しかし、.sheet(isPresented:..)のシートを使用すると、動画２のように、どの項目をタップしたとしても、最初に表示されるのは、fruitIndexの初期値である「０」番目の「りんご」が表示されてしまいます。しかし、その後、他の項目をタップすると、ちゃんと動いてくれます。

動画１
![iPhone2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3232025/0552e92c-1496-976a-24a0-ff8dd68ce2f6.gif)


動画２
![iPhone.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3232025/a3d53285-d3bc-757d-5c1c-cfc81e677240.gif)



**問題のコード**

```Swift
struct IsPresentedSheet: View {
    
    @State private var fruits = [
        Fruit(name: "りんご"),
        Fruit(name: "もも"),
        Fruit(name: "レモン"),
        Fruit(name: "ぶどう")
    ]
    @State private var isSheetPresented = false
    @State private var fruitsIndex =  0
    
    var body: some View {
        NavigationStack{
            List(fruits.indices, id: \.self) { index in
                HStack{
                    Text(fruits[index].name)
                    Spacer()
                    Button {
                        fruitsIndex = index
                        isSheetPresented = true
                    } label: {
                        Image(systemName: "info.circle.fill")
                    }
                }
            }
            .sheet(isPresented: $isSheetPresented) {
                SheetView(
                    fruitNewItem: fruits[fruitsIndex].name
                )
            }
        }
    }
}

struct SheetView: View {
    
    @Environment(\.dismiss) var dismiss
    @State var fruitNewItem: String
    
    var body: some View {
        NavigationStack{
            HStack{
                Text("名前")
                TextField("", text: $fruitNewItem)
                    .frame(width: 210,height: 50)
                    .border(Color.black)
                    .padding()
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("Cancel"){
                        dismiss()
                    }
                }
            }
        }
    }
}
```

# 解決方法

１.sheet(item:onDismiss:content:)を使用する。
「item」を引数に持つsheetを使用すると、こういった挙動は改善されます。しかし、なぜこのようなな違いが出てくるのかまでは突き止めることができませんでした。理由をご存知の方がいましたら、是非ご鞭撻頂けたらと思います。


# ちなみに
var body: some View直下にlet _ = print(fruitsIndex)でアクセスするか、Listのコードブロックの最後に.onChange内でfruitsIndexをprintすると、ちゃんと表示してくれることが確認できました。最初にViewが描画される時に、プロパティにアクセスすると、この謎挙動が修正されるのでしょうか？
【SwiftUI】順番付きで重複のないリストの作り方

# はじめに
SwiftUIでアプリを開発していて、重複のないリストを作りたいと思いました。

まず、重複のないデータを扱うためにSetを使うことを考えました。しかし、Setは順番を保持しないため私の目的には合いませんでした。

そこで、Appleが公開しているライブラリ「OrderedCollections」を使うことにしました。このライブラリをインポートすると、重複がなく順番を保持できるOrderedSetという型を使用できます。これを使えば、私の目的を達成できそうです。

# 手順
## 1. ライブラリをインストールする

File > Add Packages...を選択
![スクリーンショット 2023-07-27 20.24.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366249/985c8e6b-90b9-b02a-10f3-6c5a83d4584d.png)

Apple Swift Packagesにあるswift-collectionsを選択
![スクリーンショット 2023-07-27 20.25.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366249/ee4daf04-dac2-0372-56c7-808a7ba4f447.png)

OrderedCollectionsにチェックを入れてAdd Package
![スクリーンショット 2023-07-27 20.25.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366249/4ecd98b0-ab07-bb15-1d5e-a390f339606d.png)

## 2. コードを書く
### コード全体
```swift
import SwiftUI

// OrderedCollectionsをインポート
import OrderedCollections

struct ContentView: View {

    // OrderedSetを使う
    @State private var people: OrderedSet<String> = [
        "ジョブズ",
        "ウォズ",
        "クック",
        "ジョニー",
        "ジョン",
        "エディ",
        "フィル",
        "クレイグ",
        "アンジェラ"
    ]
    
    var body: some View {
        NavigationStack {
            List {

                // 重複がないのでidに.selfを指定してもバグが起きない
                ForEach(people, id: \.self) { person in
                    HStack {
                        Text(person)
                        Spacer()
                        Button {
                            people.remove(person)
                        } label: {
                            Image(systemName: "minus.circle.fill")
                                .symbolRenderingMode(.palette)
                                .foregroundStyle(.white,.red)
                        }
                        .buttonStyle(.plain)
                    }
                }
            }
            .animation(.easeInOut, value: people)
            .toolbar {
                Button {

                    // すでにpeopleに"ジョブズ"が入っていると追加できない
                    // "ジョブズ"を削除すると追加できる
                    people.append("ジョブズ")
                } label: {
                    Image(systemName: "plus")
                }
            }
        }
    }
}
```

このコードを実行すると、最初はプラスボタンを押しても何も起きません。しかし、"ジョブズ"を削除してからプラスボタンを押すと"ジョブズ"が追加されます。OrderedSetがうまく機能していることがわかります。

# おわりに
SwiftUIで重複のないリストを作る方法を紹介しました。この記事が参考になったという方は、いいねとフォローよろしくお願いします。

# 参考文献

https://github.com/apple/swift-collections

https://github.com/apple/swift-collections/blob/main/Documentation/OrderedSet.md
Flutter🐋audioplayers を使ったのに ios, android 端末で音が鳴らない、小さい時の対処法

AudioPlayer の Global 設定を変更する必要があります。

下記のような関数を作成した場合、

初期化(initialization)時に

`initAudioPlayer()`

を実行してください。

下記のコードはゲームSE を鳴らす場合を想定した設定項目です。

```
import 'package:audioplayers/audioplayers.dart';


final AudioContext audioContext = AudioContext(
  iOS: AudioContextIOS(
    category: AVAudioSessionCategory.ambient,
    options: [
      AVAudioSessionOptions.defaultToSpeaker,
      AVAudioSessionOptions.mixWithOthers,
      AVAudioSessionOptions.allowAirPlay,
      AVAudioSessionOptions.allowBluetooth,
      AVAudioSessionOptions.allowBluetoothA2DP,
    ],
  ),
  android: AudioContextAndroid(
    isSpeakerphoneOn: true,
    stayAwake: true,
    contentType: AndroidContentType.sonification,
    usageType: AndroidUsageType.assistanceSonification,
    audioFocus: AndroidAudioFocus.none,
  ),
);

void initAudioPlayer() =>
    AudioPlayer.global.setGlobalAudioContext(audioContext);
```

音楽プレイヤーアプリ、ゲームSE など場合によって設定を使い分けてね。AudioPlayers 有能。
tarコマンドで展開時に ._ で始まる謎のファイルが出てきて困った

圧縮されたファイルをtarコマンドで展開した際に `._` で始まる謎のファイルが出てきて困りました。
この対処法と原因について記述します。

# 結論

`$ tar -xvf --exclude '._*' src.tar`

`--exclude` オプションを利用して `._` で始まるファイルが展開されないように指定するとOKです。

参考：[【 tar 】コマンド――アーカイブファイルを作成する／展開する](https://atmarkit.itmedia.co.jp/ait/articles/1608/15/news015.html)

# 補足

`$ tar -cvf --exclude '._*' src.tar src1 src2 src3`

圧縮時に `--exclude` オプションを利用して `._` で始まるファイルを含めないようにすることも出来ます。

# 前提

- 圧縮したときの環境：Mac
- 展開したときの環境：Linux

# 原因

Mac特有の隠しファイルが圧縮時に含まれてしまっており、それをLinux（Mac以外の環境）で展開したことが原因でした。

`._` で始まるファイルは、アイコンやウィンドウの形状、メニューの内容や定義などといった情報を持つ **リソースフォーク** という隠しファイルです。
これがMacにおいて各ファイルそれぞれに1つ存在しており、圧縮時に知らずのうち含まれてしまっていたために、Mac以外の環境において展開時に現れたということでした。

ちなみに、Mac上で圧縮・展開をしても通常リソースフォークは見えません。
ABC086C-Travelingの嘘解法を解く（Javascript版）

どうもアットコーダーをJavascriptで解いてる野蛮人です。
300の問題、Travelingを解いてたのですが、どうしても解けなくて以下の記事を参考にしたところ、
https://qiita.com/ytanto/items/caf7bf0ba287da81b20f

まさかの**WA**！！
前の距離から次の目的地までが移動可能かがロジックに入っていないため、失敗するようでした。
私と同じ難民が出たらと思い、正解コードを晒しておきます。

```javascript:Javascript
function Main(i) {
  let a = i.split(`\n`);
  a.pop();

  let total = [];

  for (let i = 0; i < Number(a[0]); i++) {
    if (i == 0) {
      let array = a[1].split(" ");
      let t = Number(array[0]);
      let x = Number(array[1]);
      let y = Number(array[2]);

      if (t >= x + y && t % 2 == (x + y) % 2) {
        total.push(true);
      } else {
        total.push(false);
      }
    } else {
      let array1 = a[i].split(" ");
      let array2 = a[i + 1].split(" ");

      let t1 = Number(array1[0]);
      let x1 = Number(array1[1]);
      let y1 = Number(array1[2]);
      let t2 = Number(array2[0]);
      let x2 = Number(array2[1]);
      let y2 = Number(array2[2]);
      let nextDistance = x1 + y1 - (x2 + y2);
      let nextDistance2 = x1 + x2 - (y1 + y2);

      if (
        Math.abs(t2 - t1) % 2 == Math.abs(nextDistance2) % 2 
        //奇偶数が一致しないとピッタリ止まれない
        &&
        t2 - t1 >= Math.abs(nextDistance)
        //次の地点へ移動可能な時間か判定する
      ) {
        total.push(true);
      } else {
        total.push(false);
      }
    }
  }

  let res = total.every((n) => {
    return n;
  });

  if (res) {
    console.log("Yes");
  } else {
    console.log("No");
  }
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));

```
せんせー、ウェアラブルってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/94c726b9-508a-c171-b89a-30175b093050.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/96208674-4348-f242-5ba6-a50592e735c9.png)

せんせー、ウェアラブルってなに？

# ウェアラブルとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/bb4aaa2b-9535-ee79-e26f-565ab183fc37.png)


ウェアラブルとは、
日本語で「身に着けることができる」という意味です。
ウェアラブルテクノロジーとは、私たちが身につけて使うことのできる電子機器のことを指します。
これは、コンピューターやスマートフォンのようなものが小さくて軽くなり、
私たちの体の一部のように使うことができるようになったからです。

例えば、
あなたがお姫様ごっこをしていて、魔法の指輪があると想像してみましょう。
その指輪は特別で、それをはめると、お母さんにメッセージを送ったり、
何時間遊んだかを教えてくれたり、外で遊んでいても家に帰る時間を教えてくれるとします。

実際のウェアラブルテクノロジーも、
まさにこのような「魔法の指輪」のようなものです。

例えば、
スマートウォッチは手首にはめる時計のような形をしていますが、
それはただ時間を教えてくれるだけではありません。歩いた距離を測ったり、
心拍数を計ったり、メッセージを送ったり受け取ったりすることもできます。

このように、
ウェアラブルテクノロジーは私たちが身につけることで、遊びや生活をもっと楽しく、
便利に、そして健康的にする手助けをしてくれます。それが「ウェアラブル」の意味するところです。

# まとめ

ウェアラブルテクノロジーとは、私たちが身につけて使うことのできる電子機器のことを指します。
せんせー、IoTってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/94c726b9-508a-c171-b89a-30175b093050.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/96208674-4348-f242-5ba6-a50592e735c9.png)

せんせー、IoTってなに？

# IoTとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2fb3d51a-e74e-1fa3-033c-08c05a239e21.png)


「IoT」は「Internet of Things」の略で、これを日本語にすると「モノのインターネット」になります。それでは、具体的に何を意味するのか、おもちゃを使った例を考えてみましょう。

あなたがお気に入りのぬいぐるみがあるとします。
でも、それはただのぬいぐるみで、動いたりしゃべったりはしないですよね。
でも、IoTの力を使うと、そのぬいぐるみが特別な力を手に入れることができます。

IoTを使えば、ぬいぐるみに小さなコンピュータを入れることができます。
そしてそのコンピュータはインターネットにつながっています。
そうすると、ぬいぐるみはあなたが学校から帰ったときに「おかえり！」と言ったり、
おやすみの時間になったら「おやすみなさい！」と言ったりすることができます。

それは、ぬいぐるみがインターネットを通じて情報を得て、それに反応して行動するからです。
それが「モノのインターネット」、つまりIoTの一例です。

もちろん、
現実のIoTはもっと複雑で、家の中の機器を制御したり、
大きな工場の機械を遠隔で動かしたり、そして健康状態をチェックしたりするために使われています。

でも、
基本的な考え方はぬいぐるみの例と同じです。
それぞれの「モノ」がインターネットにつながって、情報を得て反応することで、
私たちの生活を便利にしたり、助けたりするのです。

# まとめ

それぞれの「モノ」がインターネットにつながって、情報を得て反応することで、
私たちの生活を便利にしたり、助けたりするものです。
表記法（キャメルケース、スネークケース、ケバブケース）の違いを ChatGPT に”書いてもらった”

# 表記法: キャメルケース、スネークケース、ケバブケース
### キャメルケース (Camel Case)
キャメルケースは、複数の単語を組み合わせて新しい単語を作る際に使用される表記法です。最初の単語は小文字で始まり、その後の各単語は大文字で始まります。例えば、`firstName`や`isAvailable`のようになります。この表記法は、JavaScriptやJavaなどのプログラミング言語でよく使用されます。
### スネークケース (Snake Case)
スネークケースは、複数の単語をアンダースコア(_)で結びつける表記法です。全ての文字は小文字で書かれます。例えば、`first_name`や`is_available`のようになります。この表記法は、PythonやRubyなどのプログラミング言語でよく使用されます。
### ケバブケース (Kebab Case)
ケバブケースは、複数の単語をハイフン(-)で結びつける表記法です。全ての文字は小文字で書かれます。例えば、`first-name`や`is-available`のようになります。この表記法は、URLやHTMLのクラス名でよく使用されます。


これらの表記法は、コードの可読性を高めるために重要です。どの表記法を使用するかは、使用するプログラミング言語やプロジェクトの規約によります。

## メリットデメリット

| ケース | メリット | デメリット |
|---------|--------|-------|
| キャメルケース | 読みやすく、JavaScriptやJavaなどの言語で一般的。単語の区切りが明確。 | 全ての単語が連結されているため、一部のテキストエディタでは単語の区切りが認識されない場合がある。 |
| スネークケース | 単語の区切りが非常に明確。PythonやRubyなどの言語で一般的。 | アンダースコアは視覚的に目立たないため、読みにくいと感じる人もいる。また、URLでは使用できない。 |
| ケバブケース | 単語の区切りが明確で、URLやHTMLのクラス名で一般的。 | ハイフンはマイナス記号として解釈される可能性があるため、プログラミング言語では使用できない場合がある。 |
出先でも快適な開発環境をVSCode Remote SSH+Tailscale+スマートプラグで手に入れる

お盆に時期で帰省される方も多いかと思います。
Qiitaを読まれる方の多くは帰省したときにラップトップを持ち帰るなどして、いつでも開発をできるようにしているかと思います。
私も必ずラップトップを持ち帰り、暇があれば開発などができるようにしていました。
~~実際はそんな暇がなくて一度も起動しないことが多いですが~~

その時、いつも以下のような不満がありました
- ラップトップの性能が低くてビルドなどに時間がかかる
- モバイル回線を使うため、回線が遅くて`docker pull`などに時間がかかる

これらをタイトルにあるようにVSCode Remote+Tailscale+スマートプラグを組み合わせることで、改善できそうだったので紹介します


# VSCode Remote SSH

デスクトップPCなど性能の高いPCが自宅にあることが前提ですが、そうしたPCは基本的にラップトップより性能が高いです。また、そのPCにリモートで接続して開発することで`docker pull`などをしても自宅の回線で実行されるためモバイル回線の遅さやギガの残高を気にする必要がなくなります。

そしてそのリモートを快適に行うために使うのが、`Visual Studio Code Remote - SSH`という拡張機能です。
https://code.visualstudio.com/docs/remote/ssh

この拡張機能は、sshさえできれば接続先の環境でもまるでローカルで開発しているかのような体験を得ることができます。
また、特にすごいのが`yarn start`などでリモート先のPCで例えば3000ポートでサーバが起動した場合、内部でよしなにされてローカルのPCのブラウザで`localhost:3000`で接続できてしまうところです。
これができれば、ほとんどのweb開発は不自由なくできるのではないでしょうか。

# Tailscale

これは簡単に自宅PCに接続できるようにするために利用します。
出先からsshで接続する場合、自宅のルータの設定をいじってポート開放と呼ばれる作業をしたり自宅のLANに入るためにVPNサーバーを建てるなどする方法が思いつきます。
しかし、これらの方法は自宅の回線がDS-Liteの場合はポート開放をできなかったり、VPNサーバー建てるのが面倒だったりで課題があります。

Tailscaleはこうした用途に最適です。
https://tailscale.com/

自宅のPCと出先で使うラップトップの双方にインストールすることで直接VPN接続を行い、そのVPNの上でssh接続をします。
ブラウザでtailscaleのサイトを開いてログインすると、自分の接続しているデバイスを一覧を見ることができるので、そのIPアドレスなどをコピペすることで簡単にssh接続ができます。もちろん、自宅側もラップトップ側も多くの場合はルータの設定等なしに接続が可能です。
更に、Tailscaleは無料プランでも100台まで接続可能なので、普通に使ってる分には無料のままで利用可能です。

# スマートプラグ

自宅PCにリモートで接続できるようにはなりましたが、常に使うわけではないのに起動しっぱなしでは電気代が気になります。
そこで、スマートプラグを用います。

スマートプラグは、遠隔でコンセントの電源をON/OFFできる製品で、1台あたり1k~2K円程度で購入可能です。
ただ、あくまでもコンセントのON/OFFができるだけで、ただつないだだけではPCの電源をONにすることはできません。
しかし、実は（おそらくほとんどの）マザーボードには「通電したら自動で電源をONにする」機能があるため、BIOSの設定でその機能を有効にすることで出先からスマートプラグをOFFからONにすることで遠隔でPCの電源を入れることができます。

私のPCはASRockのB450M Steel Legendなので、Restore on AC Power lossでPower Onにすることで設定できました。
![WIN_20230727_08_40_43_Pro.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206013/5794655f-e826-765d-43c3-8b0b5728e0f5.jpeg)


ただ、やや調子悪く、スマートプラグでONにしても起動しないことがありました。何度すれば起動はするので、TailscaleのIP宛にpingしながら操作するようにしています。

スマートプラグを接続しておくことはもう一つメリットがあって、リモートで接続している接続先のPCがハングしてssh越しではどうにもならなくなることがまれによくありますが、強制的にシャットダウン(というか電源断)することができるのでそういう場合にも対応できるようになります。電源をいきなり止めるのでPCにはだいぶ悪そうですが。

# 蛇足

VSCode以外にも利用用途を考えていて、~~何とは言わないですが~~ 許可なくアプリのインストールをできないmacOSやWindowsへのアクセスもできたりします。

macOSはVNC、WindowsはRDPがOS標準で使えます。
sshはポートフォワーディングと呼ばれる機能があり、前述の自宅PCへのssh接続を経由することで自宅PCと同じLAN内にある端末へアクセスできます。

これを組み合わせることで、例えば以下のようなコマンドを手元のラップトップなどで実行しておくことで、手元のラップトップのVNCクライアントから`localhost`でmacOSを遠隔操作できたりします。

`ssh -L 5900:<macOSのローカルIP>:5900 <自宅PCのuser>@<自宅PCのTailscale上のIP>`


※ ただし、macOSのマシンは起動しっぱなしにする必要はあります。


では、よい休日を
リソース名から料金が発生している Compute Engine リソースを調査する

# リソース名から料金が発生している Compute Engine リソースを調査する

## はじめに
弊社ではクラウドサービスの料金の可視化サービスの Vantage を使っています。
Vantage では複数のクラウドの料金を一つのプラットフォームで見ることができます。
https://www.vantage.sh/

Vantage では Google Cloud の料金も見ることができます。
今まではサービスごとの料金のみだったのですが、2023年6月から Compute Engine はリソースごとの料金が見れるようになりました。
表ではリソース名で表記されています。
![vantage_gce一覧.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/71147f09-4c18-079b-58fb-74225d3084a3.png)


### リソース名とは？

Google Cloud 内部でリソースごとに割り当てられている文字列で、一意の値です。

https://cloud.google.com/apis/design/resource_names?hl=ja
> 各リソースには、独自の一意のリソース名が必要です。

Compute Engine インスタンスのリソース名の形式は
```
//compute.googleapis.com/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_ID
```
となっています。
そのほか、例えば Compute Engine スナップショットだと上記の `instances` の部分が `snapshot` になります。

Vantage では Compute Engine のリソース名のみ表示されていますが、BigQuery など他のサービスでもリソース名を持っています。

https://cloud.google.com/iam/docs/full-resource-names?hl=ja

### Vantage の参照元

Vantage は BigQuery にエクスポートされた請求書データテーブルを参照しています。
Vantage の `Resource` 列に表示されている値は「詳細な使用料金テーブル `gcp_billing_export_resource` 」の `resource.global_name` を参照していると思われます。
`resource` の中身は画像のようになっています。
（`resource.name` はコンソールなどで確認できる名前）
![resource.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/610cc1d5-b536-f061-9096-bdbc1a6020b1.png)

BigQuery にエクスポートされる請求書テーブルの詳細は公式ドキュメントを確認してください。

https://cloud.google.com/billing/docs/how-to/export-data-bigquery-tables?hl=ja

## リソース名からリソースを特定する方法
BigQuery の請求書データテーブルから検索できます。

実行するクエリは以下のように、`WHERE` 句に調べたいリソース名を指定します。
``` sql
SELECT resource FROM `<PROJECT ID>.billing_data.gcp_billing_export_resource_v1_<BILLING_ACCOUNT_ID>`
 WHERE TIMESTAMP_TRUNC(_PARTITIONTIME, DAY) = TIMESTAMP("2023-07-27")
 AND resource.global_name = '検索したいリソース名'
```

※指定する `TIMESTAMP` について、データセットタブからクエリタブを開いたときは当日の日付になりますが、データが格納されておらｓず 0 ヒットになる場合があります。数日前の日付を入力してください。


### Compute Engine VM インスタンスのリソースIDを特定する方法
特定のインスタンスのリソースIDは、コンソールや gcloud などで確認できるようですが、対応しているのは VM インスタンスのみで、スナップショットやディスクは確認できないようです。

https://cloud.google.com/compute/docs/instances/get-instance-id?hl=ja#api

以上です。どなたかの参考になれば幸いです。
Gogsをdocker-composeで動かす方法

# はじめに
GitHubのような環境が手元に欲しくて探したところ[Gogs](https://gogs.io)というGitHubクローンのOSSがあった。しかし、Gogsを使うにはデータベースも別途、用意しないといけないと分かったのでdocker-composeを使って、さっくりとGogsを立ち上げられるようにした。
そのとき使ったdocker-compose.ymlと方法をここにメモしておく。

# docker-composeの軽い説明
docker-composeを使うと複数のDockerコンテナを協調動作させるようなサービスを簡単に建てられるようになる。使い方はとても簡単。

1. 空のフォルダを作る
2. 中にdocker-compose.ymlを置く
3. フォルダ内で`docker-compose up -d`を実行する

これだけでお手軽にサービスを立ち上げることができる。
コンテナ群を停止させるときは`docker-compose down`を実行するだけ。

# docker-compose.yml
Postgresのパスワードは`#####`と書いているが、ここは各自で設定する。
ポートの番号は、[Gogs公式に書いてあるDockerで動かすときのやり方](https://github.com/gogs/gogs/tree/main/docker)に従っている。
`restart: always`を設定しているのでホスト側を再起動しても自動でGogsが立ち上がるようになるはず。
```yml
version: '3'
services:
  db:
    image: postgres:latest
    environment:
      - POSTGRES_USER=gogs
      - POSTGRES_PASSWORD=#####
      - POSTGRES_DB=gogs
    volumes:
      - ./dbdata:/var/lib/postgresql/data
    restart: always
  gogs:
    image: gogs/gogs
    ports:
      - "10880:3000"
      - "10022:22"
    depends_on:
      - db
    volumes:
      - ./data:/data
    restart: always
```

# gogsの設定
まず、`docker-compose up -d`を実行すると、こんな感じで色々と出てくる。
```terminal
# docker-compose up -d
[+] Running 3/3
 ✔ Network gogs_default   Created                                          0.1s 
 ✔ Container gogs-db-1    Created                                          0.0s 
 ✔ Container gogs-gogs-1  Created                                          0.1s 
...
```
この表示は環境によって違うのでしっかりよく見て、`gogs-db-1`の部分をメモっておくこと。gogsの初期設定のときに使う。

docker-composeの処理が終わったら、ローカルで実行している場合は、ブラウザで`127.0.0.1:10880`にアクセスすると下のような設定画面が出てくる。ローカルで実行していない場合は`127.0.0.1`の部分をそのアドレスに変えて実行する。
![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280972/82ed3550-2532-2e51-a224-871bfd4b3bb0.png)

設定に関しては基本的に[ここ](https://github.com/gogs/gogs/tree/main/docker)に従えば良い。

上から変更する部分を書くと、

1. **Host** : gogs-db-1など`docker-compose up -d`を実行したときにメモした名前にする
2. **Password** : docker-compose.ymlで設定したパスワードにする
3. **Domain** : リモートで動かす場合はサーバーにsshでアクセスするときの名前にする
4. **SSH Port** : 10022にする
5. **Application URL** : `http://127.0.0.1:10880`にする（リモートで動かす場合は、`127.0.0.1`をそのサーバーのIPアドレスやドメインにする）

変更し終えたら、Install Gogsを押すとGogsのログイン画面が表示される。
![img2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280972/a77c3a73-dea1-d5bd-9836-963184fc683d.png)

まだアカウントは持っていないので、下にあるSign up now.からアカウントを登録して、ログインすると使えるようになる。

Gogs自体の使い方はGitHubにかなり近いので省略。

# Gogsの初期設定をミスったときの修正方法
ちゃんとやりたい人は[ここ](https://gogs.io/docs/installation/configuration_and_run)に従ったほうがいいかも？
ただ自分は面倒なので設定ファイルを直にいじった。

1. `docker-compose down`を実行してGogsを止める
2. コンテナが停止したら、テキストエディタで`data/gogs/conf/app.ini`を開く
3. 修正したいところを書き換える
4. `docker-compose up -d`を実行してGogsを再起動

Domainを間違えて設定したときは、この方法でもちゃんと変更された。

# おわりに
本記事は備忘録的なものですが、間違えや質問があったらぜひコメントください。
お待ちしております。
Javaのメソッドについて学習してみた

# 概要
Javaのメソッドについて学習してみました。以下のページを参考にしました。

メソッドの利用

https://www.javadrive.jp/start/method/

メソッドの使い方

https://www.javadrive.jp/start/method/index1.html

メソッドの定義

https://www.javadrive.jp/start/method/index2.html

引数を使ってメソッドに値を渡す

https://www.javadrive.jp/start/method/index3.html

引数に配列やクラスオブジェクトを渡す

https://www.javadrive.jp/start/method/index4.html

戻り値を使ってメソッドから値を返す

https://www.javadrive.jp/start/method/index5.html

戻り値として配列を返す

https://www.javadrive.jp/start/method/index6.html

return文

https://www.javadrive.jp/start/method/index7.html

メソッドのオーバーロード

https://www.javadrive.jp/start/method/index8.html

可変引数

https://www.javadrive.jp/start/method/index9.html

固定引数と可変引数の組み合わせ

https://www.javadrive.jp/start/method/index10.html

# まとめ
何かの役に立てばと。
Go言語で SQL query に（可変長な）複数のパラメータを渡したい

# 初めに
Go言語においてSQLのqueryに（可変長な）複数のパラメータの渡したかったのですが、いい記事が見つからなかったのでまとめてみました！同じことで困っている人の一助になれれば幸いです！！

# 環境
Hard: **Inter Mac**
OS: **Monterey 12.0.1**
Golang: **go version go1.20.5 darwin/amd64**

# 事前に知っていたこと
Go言語ではsymbol(手元の環境では '?' )を SQL query に指定することで変数を受け取り可能です。
一つの例を示します。

```ex1.go
rows, _ := db.Query("SELECT * FROM テーブル名 WHERE address LIKE '%?'",変数)
```
（[参考資料](https://graff-it-i.com/2021/06/24/golang-mysql-like/)より引用）

# やりたいこと
上記の query で指定している**変数**が状況に応じて要素数が変化するような**配列データ**だった場合に、Go言語ではどのように記述することができるのでしょうか？

# 事前情報をもとにできたこと
複数の値を指定したい場合は、**配列データ**の要素数分symbolを追加してやれば良いので下記のように書くことが可能です。（カンマ区切りで複数指定可能）
```ex2.go
// arr は可変長の配列
strings.Repeat(",<環境に合ったsymbol>", len(arr)-1)
```
rep_str := strings.Repeat は第一引数の文字列を第二引数回繰り返し結合した文字列を出力する関数です。 query にこの rep_str を fmt.Sprintf などで結合させれば、引数を arr の要素個受け付ける query の土台の完成です。

# 困ったこと
query の宣言ができた一方で、値はどのように受け渡すことができるのでしょうか...？ 直接指定？ for文で複数回指定? （Pythonなら *<配列> とすることで各要素取り出せた気がするのでGoにもそれ相当のものがある?）


# 解決方法 
Go言語では関数宣言時に引数として "...<type>" という宣言がなされている場合は 引数を渡す際に "<type型のスライスor配列> ..." のようにすることで可変長引数を渡すことが可能らしいのです。（[参考資料](https://zenn.dev/mikankitten/articles/cfa2ef834e338e)）

Go言語の[公式ドキュメント](https://pkg.go.dev/database/sql#DB.Query)でQuery実行関連の関数（DB.Query, DB.QueryRow etc...）を確認すると、下記のように定義されていることが確認できる。
```
func (db *DB) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error)
```
**"srgs ...any"** と宣言されていることから any型の配列orスライスならそのまま引数に渡せることがわかります！

any型の代表的なものとしてinterface型というものがあり、[事前情報をもとにできたこと](#事前情報をもとにできたこと)で受け取る可変長引数データのarrをinterface型に変換する（[interfaceへの変換について](https://text.baldanders.info/golang/interface/)はこちらに情報あり）ことで引数に渡すことが可能になりました！！

# 終わりに
今回はGo言語におけるSQL querへの可変長な複数パラメータの渡し方について確認しました。
Goを勉強し始めてまだ1ヶ月くらいなので間違いもたくさんあると思います。もし間違いを発見されましたらコメント等でお教えいただけると幸いです！
find

find /bin -perm 4644 4644であるもの
find /bin -perm -4644 4644の全ビットが立っているもの
find /bin -perm /4644 4644のいづれか（4000 or 0600 or 0040 or 0004)

```
      -perm mode
              File's permission bits are exactly mode (octal or symbolic).  Since an exact match is required, if  you
              want  to  use  this form for symbolic modes, you may have to specify a rather complex mode string.  For
              example `-perm g=w' will only match files which have mode 0020 (that is, ones  for  which  group  write
              permission  is  the  only  permission set).  It is more likely that you will want to use the `/' or `-'
              forms, for example `-perm -g=w', which matches any file with group write permission.  See the  EXAMPLES
              section for some illustrative examples.

       -perm -mode
              All  of  the  permission bits mode are set for the file.  Symbolic modes are accepted in this form, and
              this is usually the way in which would want to use them.  You must specify `u', `g' or `o' if you use a
              symbolic mode.   See the EXAMPLES section for some illustrative examples.

       -perm /mode
              Any  of  the permission bits mode are set for the file.  Symbolic modes are accepted in this form.  You
              must specify `u', `g' or `o' if you use a symbolic mode.  See the EXAMPLES section for  some  illustra‐
              tive  examples.  If no permission bits in mode are set, this test matches any file (the idea here is to
              be consistent with the behaviour of -perm -000).

```
[MR Dev Tips #3] アプリケーションの一時的なデータ、キャッシュを保存する方法

# はじめに
**HoloLens 2 Dev Tips #3** ということで、今回は HoloLens 2 アプリケーション開発時に、一時的にローカルストレージにデータを保存しておきたいケースで使えるストレージパスの取得方法について紹介したいと思います。

# 開発環境
- Unity 2020.3

# 内容
Unity が提供している Scripting API の ``Application.temporaryCachePath`` を利用すると、アプリを実行しているハードウェアプラットフォーム (ローカルストレージ) で、一次的なデータ保存が可能なディレクトリパスを返却してくれます。戻値の string は読み取り専用 (readonly) となっています。

```
public static string temporaryCachePath;
```

```sample.cs
using UnityEngine;

public class Example : MonoBehaviour
{
    void Start()
    {
        Debug.Log(Application.temporaryCachePath);
    }
}
```

この ``Application.temporaryCachePath`` は実行時にフォルダパス (文字列) を返却してくれるので、Unity Editor ( Windows PC ) と HoloLens 2 で、ファイルパスがどのように出力されるのかを見てみたいと思います。

**Unity Editor (PC) で実行した場合**

```
C:/Users/<UserName>/AppData/Local/Temp/<CompanyName>/<ProductName>
```

``CompanyName``、``ProductName`` は Project Settings > Player で設定している値となります。


**HoloLens 2 で実行した場合**

```
C:/Data/Users/<UserName>/AppData/Local/Packages/<PackageName>/TempState
```

以上、アプリケーションの一時的なデータ保存場所についてでした。
git コマンドメモ

## 最初に設定しておきたいこと

コミットする前にはユーザー登録の必要あり

```
git config --global user.name [ユーザー名]
git config --global user.email [メールアドレス]
```

windows 環境で clone したときに改行コードを勝手に変換させない

```
git config --global core.autocrlf false
```

## リポジトリ操作

共有可能なリモートリポジトリの作成

```
git init --bare --shared [パス(url)]
```

現在のディレクトリにリポジトリ作成

```
git init
```

リモートリポジトリの追加

```
git remote add origin [url]
```

リモートリポジトリからクローン

```
git clone [url] .
```

ディレクトリ指定にピリオドつけると、勝手にフォルダが作成されず、中身のみが展開される


コミット＆プッシュするため、まずは追加

```
git add .
```

コミット時にはメッセージが必要

```
git commit -m "なんとかかんとか"
```

最後にリモートリポジトリにプッシュする

```
git push origin master
```

originとはリモートリポジトリのエイリアスのようなもので

```
git push [url] master
```

のように、直接指定することもできる。
ブランチに tracking information を追加することで、差分を確認したり push/pull 時に指定を省略できる

```
git branch --set-upstream-to=origin/master master
```

なお clone したリポジトリは最初から設定されている模様


## サブモジュール関連

プロジェクトにサブモジュールを追加

```
git submodule add [url] [path]
```

プロジェクトからサブモジュールを削除

```
git submodule deinit -f [path]
git rm -f [path]
rm -rf .git/modules/[path]
```

最後のコマンドは linux 用で windows では delete などになると思われる。
エクスプローラー上から直接消してもいい。

プロジェクト上の全サブモジュールの更新

```
git submodule foreach git pull origin master
```

## リモートリポジトリの url 変更

現在の url の確認

```
git remote -v
```

変更処理

```
git remote set-url origin [new-url]
```

origin 以外もいけると思われる。
また、一旦 rm してから add しなおす方法もあり、内部的に違いがあるっぽい。
docker compose部署prometheus grafana和jaeger


## prometheus & grafana & pushgateway


*docker-compose.yml*

```yaml
version: '3'

services:
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
    ports:
      - '9090:9090'
    extra_hosts:
      - "host.docker.internal:host-gateway" #与host通信
  pushgateway:
    image: prom/pushgateway
    container_name: pushgateway
    ports:
      - '9091:9091'
  grafana:
    image: grafana/grafana
    container_name: grafana
    ports:
      - '3000:3000'
```

*prometheus.yml*
```yaml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'pushgateway'
    static_configs:
      - targets: ['pushgateway:9091']

  - job_name: 'grafana'
    static_configs:
      - targets: ['grafana:3000']

  - job_name: 'jaeger'
    static_configs:
      - targets: ['host.docker.internal:14269']

  - job_name: 'node-exporter'
    static_configs:
      - targets: ['host.docker.internal:9100']
```


## jaeger
*docker-compose.yml*

```yaml
version: "2"
services:
  # Jaeger
  jaeger-all-in-one:
    image: jaegertracing/all-in-one:latest
    ports:
      - "16686:16686" # Jaeger UI
      - "14268:14268" # Receive legacy OpenTracing traces, optional
      - "4317:4317"   # OTLP gRPC receiver
      - "4318:4318"   # OTLP HTTP receiver
      - "14250:14250" # Receive from external otel-collector, optional
      - "14269:14269"
    environment:
      - COLLECTOR_OTLP_ENABLED=true
```

效果:rolling_eyes:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/898077/32490178-5217-8de2-6104-f97aa1c00ddd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/898077/43dd7026-130e-28b4-f705-126f96c7f64e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/898077/6db71727-2116-a5e2-199b-13eaa0b254a8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/898077/d226713e-01c8-0b50-5a72-ecf3c0e291cf.png)
ssh-agent

ssh-agentにより、メモリ上に秘密鍵を暗号化せずに登録。
```
[linuxstudy@xxxx ~]$ ssh-agent bash
[linuxstudy@xxxx ~]$ ssh-add ~/.ssh/id_rsaEnter passphrase for /home/linuxstudy/.ssh/id_rsa: 
Identity added: /home/linuxstudy/.ssh/id_rsa (/home/linuxstudy/.ssh/id_rsa)
[linuxstudy@xxxx ~]$ ssh-add -l
2048 SHA256:/PKg8I/YfAU2UDKQ+rZSAD8WmOpjOvu9gIcpTuixGS4 /home/linuxstudy/.ssh/id_rsa (RSA)
[linuxstudy@xxxx ~]$ echo $SSH_AGENT_PID
23713
[linuxstudy@xxxx ~]$ echo $SSH_AUTH_SOCK
/tmp/ssh-TJOVZg3SypPd/agent.23712
[linuxstudy@xxxx ~]$ ps -aux | grep 2371linuxst+  23712  0.0  0.1 116436  2980 pts/0    S    18:19   0:00 bash
linuxst+  23713  0.0  0.0  72568   968 ?        Ss   18:19   0:00 ssh-agent bash
linuxst+  23854  0.0  0.0 112812   972 pts/0    S+   18:25   0:00 grep --color=auto 2371
[linuxstudy@xxxx ~]$ 

```
Athena で S3 Glacier で復元されたデータのクエリを実行する

# 内容

https://aws.amazon.com/jp/about-aws/whats-new/2023/06/amazon-athena-querying-restored-data-s3-glacier/

- Athena を使用して Glacier Flexible Retrieval ストレージクラスと Deep Archive ストレージクラスで復元されたデータを直接クエリできるようになった。

- 今までは、標準ストレージクラスにデータをコピーする必要があった。

- S3 スタンダード に保存されている最新のログと S3 Glacier Flexible Retrieval に復元された古いログを組み合わせると、1 つのクエリでストレージクラス全体のログ分析を実行することも可能。

# やってみる

## サンプルデータの準備　

S3 にサンプルデータをアップロードしておき、Glueクローラでテーブルを準備しておきます。
![スクリーンショット 2023-07-25 19.38.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/f5bfb6bc-b0e2-cab5-98ce-bc5da9e4d1c2.png)

## ストレージクラス：スタンダードでの動作確認

とりあえず、**ストレージクラス：スタンダード**で通常通り Athena からクエリし動作を確認しておきます。

```sql
SELECT * FROM "<database name>"."<table name>" limit 10;
```

![スクリーンショット 2023-07-25 19.49.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/f9cf0dae-026b-d224-60de-d91cf83ace09.png)

## ストレージクラス：Glacier Flexible Retrieva への変更

S3 で**ストレージクラス：Gacier Flexible Retrieva** に変更します。
![スクリーンショット 2023-07-25 19.50.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/77b992e2-29b4-bbdf-27aa-f015069b60c0.png)

## テーブルプロパティの変更

**ALTER TABLE SET TBLPROPERTIES** コマンドを使用してテーブルプロパティを設定しておく必要があります。

```sql
ALTER TABLE table_name SET TBLPROPERTIES ('read_restored_glacier_objects' = 'true')
```
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/querying-glacier.html

## S3 で復元を開始

S3 で復元を開始してあげます。
![スクリーンショット 2023-07-25 20.07.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/2c7f39ef-e935-2aba-aa79-b188a2ee1366.png)

## ストレージクラス：Glacier Flexible Retrieva での動作確認

同じように**ストレージクラス：Gacier Flexible Retrieva** で通常通り Athena からクエリし動作を確認します。

```sql
SELECT * FROM "<database name>"."<table name>" limit 10;
```

![スクリーンショット 2023-07-27 18.20.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/cd00b240-3813-9f33-2301-fe3fdbb0d9ce.png)
画像の差分取得

# 研究で使ったコード

Google Colabで動かしています


```python
import cv2
from google.colab.patches import cv2_imshow

def image_diff(image1_path, image2_path):
    #画像を読み込む
    img1 = cv2.imread(image1_path)
    img2 = cv2.imread(image2_path)

    #差分を計算
    diff = cv2.absdiff(img1, img2)

    #diffを白黒にしたい場合
    # diff = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
    
    #画像を表示
    cv2_imshow(diff)


if __name__ == "__main__":
    # 2枚のカラー画像のパスを指定
    img1_path =""
    img2_path ="" 
    image_diff(img1_path,img2_path)
```

***

[OpenCV](https://opencv.org/)
【PowerAutomate】配列を作る方法





## 配列を作る方法

1. `＋新しいステップ`をクリックして、変数を追加していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/c0e45cc5-4d4c-b4d6-3d63-d6f1341280a0.png)

検索窓に「変数」と入力して、[変数を初期化する]で変数を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/d3864303-c4ac-0ff8-11ac-30250bcd5655.png)

⒉ 追加したフローをクリックして展開し、名前欄にお好きな名前を設定してください。今回は果物の配列を作っていきます。

⒊ 種類のドロップダウンリストから「アレイ」を選択してください。

![スクリーンショット 2023-07-27 173502.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/30f503ac-10c0-5fd4-3123-7c150e1eaf5c.png)

⒋ 値欄に、配列の要素を設定していきます。

:::note
**記述方法**
配列の要素をカンマで区切り、鍵括弧で前後を囲って記述します。
また、配列の要素が数値ではなく文字列だった場合、要素を個別にダブルクォーテーションで囲ってあげる必要があります。
:::


今回は果物の配列なので、ダブルクォーテーションで囲って記述します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/3844be0a-6cfa-db78-3e78-c38150edeced.png)

これで準備完了です！

## フローを実行して中身を確認してみる

1. 先程と同じように`＋新しいステップ`をクリックして、「コントロール」を検索、[それぞれに適用する]を選択してください。分かりにくいですが、こちらがforeachと同じ役割(要素すべてを処理する)を持つコントロールになります。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/6b1ed7da-8cb1-2701-da72-2e1caec29118.png)

⒉ 追加したフローをクリックして展開し、作成した配列を選択してください。

![スクリーンショット 2023-07-27 175545.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/85e5a072-46f9-362a-f94d-5a7492dedde8.png)


⒊ 処理する配列をセットしたら、一つずつ処理するように設定していきます。[Apply to each]内のアクションの追加ボタンをクリックして、「データ操作」を検索し、[作成]コントロールを押してください。
![スクリーンショット 2023-07-27 175815.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/e98e2fd0-4e70-2bba-bc29-a5dc13157f1c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/5d06b738-8071-12ef-7048-be71007ee05b.png)

⒋ 作成を展開し、入力窓をクリックして、現在のアイテムを選択します。
![スクリーンショット 2023-07-27 180230.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/1311b109-9261-13d5-9fc2-9805a455c589.png)


以上の設定が終わったら、保存→右上のテストをクリックして、手動で「フローの実行」を行ってみましょう。
フローの実行の後に完了ボタンを押すと、実行結果を確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/b73d77ad-dd8f-092c-e875-616a8af97fd5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/adafa096-0efb-0ef4-bee0-896f02213f58.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/b0a9852a-424c-7dcd-fb67-850f65a4988b.png)

無事、配列を作成し、中身を確認することができました！


## おまけ

配列に要素を追加することもできます。

`＋新しいステップ`をクリックして、検索窓に「変数」と入力し、[配列変数に追加]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/50321f29-938b-49c9-1e5b-a29e007a87e4.png)

名前欄で、追加したい配列を選択し、値欄に配列の要素を入力します。
※この時は、文字列だとしてもダブルクォーテーションで囲う必要はありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/f708400b-8735-e9d3-43c8-8c86f15b5781.png)

実行すると…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3069823/132375c4-4dbd-4fb2-e312-97c8b4a0747b.png)

配列の要素を追加することができました！！

## おわりに

読んでいただきありがとうございました！
お役に立てれば幸いです。
[Azure Databricks] セキュリティのベストプラクティス（翻訳）

# はじめに

https://learn.microsoft.com/ja-jp/azure/databricks/lakehouse-architecture/security-compliance-and-privacy/best-practices

Azure Databricksのドキュメント（Microsoft Learn）で、セキュリティのベストプラクティスについてかかれている章がまだ日本語訳されていなかったため、DeepLで翻訳しました。

# セキュリティのベストプラクティス

セキュリティのベストプラクティスは Databricks Security and Trust Center の [Security Features](https://www.databricks.com/trust#security-features) にあります。

詳細については、このPDFを参照してください： [Azure Databricks Security Best Practices and Threat Model](https://cms.databricks.com/sites/default/files/2023-03/Azure-Databricks-Security-Best-Practices-and-Threat-Model.pdf).

以下のセクションでは、この柱の原則(the principles of this pillar)に沿って PDF に記載されているベストプラクティスをリストアップします。

## 1. 最小権限を使用した ID とアクセスの管理

- シングルサインオンによる認証
- 多要素認証を使用する
- ローカルパスワードを無効にする
- 複雑なローカルパスワードを設定する
- 管理者アカウントを通常のユーザーアカウントから分離する
- トークン管理を使用する
- ユーザとグループのSCIM同期
- クラスタ作成権限を制限する
- シークレットの安全な保管と使用
- クロスアカウントIAMロール設定
- 顧客が承認したワークスペースへのログイン
- ユーザー分離をサポートするクラスタを使用する
- サービスプリンシパルを使用して本番ジョブを実行する

詳細は、この記事の冒頭で参照したPDFに記載されています。

## 2. 転送中および停止中のデータを保護する

- 本番データをDBFSに保存しない
- クラウド・ストレージへのアクセスを保護する
- 管理コンソール内でデータ流出設定を使用する
- バケットのバージョニングを使用する
- ストレージを暗号化し、アクセスを制限する
- マネージド・サービスに顧客管理キーを追加する
- ワークスペース・ストレージ用に顧客管理キーを追加する
 
詳細は冒頭のPDFを参照してください。

## 3. ネットワークの保護、エンドポイントの特定と保護

- 顧客管理のVPCまたはVNetで展開する
- IPアクセスリストを使用する
- ネットワーク流出防止策を導入する
- VPCサービス・コントロールを適用します
- VPCエンドポイントポリシーを使用します
- PrivateLinkを設定する

詳細は、この記事の冒頭で参照したPDFに記載されています。

## 4. 責任共有モデルの確認

- 共有責任モデルを確認します。

詳細は本記事の冒頭付近で参照されているPDFに記載されています。

## 5. コンプライアンスおよびデータプライバシー要件を満たす

- Databricks のコンプライアンスプログラムを確認する。

詳細は本記事の冒頭で紹介したPDFを参照してください。

## 6. システムセキュリティの監視

- Databricksの監査ログ配信を利用する
- 使用量を監視し、チャージバックを可能にするためにタグを設定する
- Overwatchを使用してワークスペースを監視する
- プロビジョニングアクティビティを監視する
- 拡張セキュリティ監視またはコンプライアンス・セキュリティ・プロファイルを使用する

詳細は本記事の冒頭で紹介したPDFを参照してください。

## 一般的なコントロール

- サービスクォータ
- ライブラリの制御
- 機密性の高いワークロードを別のワークスペースに隔離する
- CI/CDプロセスを使って、コードにハードコードされた秘密がないかスキャンする

詳細は、この記事の冒頭で紹介したPDFを参照されたい。
[AWS Q&A 365][AppSync]AWSのよくある問題の毎日5選 #99

# 1. AWS AppSyncのリアルタイムデータとは何ですか？
答え：AWS AppSyncのリアルタイムデータとは、バックエンドのデータソースでデータが変更されるたびにリアルタイムで更新を受け取る能力のことを指します。

# 2. AWS AppSyncでリアルタイムデータをどのように有効にできますか？
答え：AWS AppSyncでリアルタイムデータを有効にするには、データが変更されるたびにクライアントがリアルタイムで更新を受け取ることを可能にするAWS AppSyncのサブスクリプションを使用します。

# 3. AWS AppSyncでリアルタイムデータを有効にするためにどのデータソースを使用できますか？
答え：リアルタイムデータは、Amazon DynamoDB、AWS Lambda、HTTP APIなどのデータソースと共に、AWS AppSyncで有効にすることができます。

# 4. AWS AppSyncのリアルタイムデータへのアクセスをどのように制御できますか？
答え：AWS AppSyncのリアルタイムデータへのアクセスは、Amazon Cognitoユーザープールを使用してフィールドレベルで制御することができます。これは、細かいアクセス制御を提供します。

# 5. AWS AppSyncを使用してリアルタイムアプリケーションを構築することができますか？
答え：はい、AWS AppSyncはリアルタイムデータの更新を有効にし、リアルタイムのサブスクリプションをサポートすることで、リアルタイムアプリケーションの構築を可能にします。
[AWS Q&A 365][AppSync]Daily Five Common Questions #99

# 1. What is Real-time data in AWS AppSync? 
Answer: Real-time data in AWS AppSync is the ability to receive real-time updates as data changes in the back-end data sources connected to the GraphQL API. 

# 2. How can I enable real-time data in AWS AppSync? 
Answer: Real-time data can be enabled in AWS AppSync by using AWS AppSync subscriptions, which allow clients to receive real-time updates as data changes. 

# 3. What data sources can I use to enable real-time data in AWS AppSync? 
Answer: Real-time data in AWS AppSync can be enabled with data sources such as Amazon DynamoDB, AWS Lambda, and HTTP APIs. 

# 4. How can I control access to real-time data in AWS AppSync? 
Answer: Access to real-time data in AWS AppSync can be controlled at a per-field level using Amazon Cognito user pools, which provide fine-grained access control. 

# 5. Can I build real-time applications using AWS AppSync? 
Answer: Yes, AWS AppSync provides the ability to build real-time applications by enabling real-time data updates and providing support for real-time subscriptions.
新米スクラムマスター書紀

２か月間スクラムマスターを経験した私が、将来の自分に向けて語り継ぐためのものです:muscle_tone2:
反省多めです。

# 困難だったこと


### 声かけと見守りのバランス
非常に素晴らしいメンバが集まっている中、初めてのスクラムマスターという目に見えないプレッシャーがありました。「できるだけ余計な声かけはせずにチームを観察しよう」とすると、どうしても気になることが出てきたり、自分は何もチームに貢献できてないのでは？という焦りが生まれます。


### タイムマネジメントがグダる
以前と比べて少し大きめのチームになってきたこともあり、
デイリーやレトロスペクティブを同じ調子でやっていると時間が足りなくなります。
メンバが増える分スプリントバックログも増え、インクリメントが追いづらくなったり、一人ひとりに気が配り切れていないのでは、という焦りがありました。
デイリーのアジェンダを見直したり、レトロもテーマを絞るなど工夫してみましたが、なかなか収拾がつかず仕舞いでした。。


# やったこと

### お祭り感を演出
完成できなかったバックログがあると、スプリントレビューがお通夜と化します。
テンションが下がるのは当たり前です。自分たちで見積もって、プランニングして、全力で集中してコミットしてきた証拠だ、ということをチームに伝えました。

それから、レビューでの「祭り感」を出すため、スプリントMVPと題してメンバ同士でお題にそって投票、発表の時間を設けました。お題は、チームで大切にしたいこと（カイゼン、雑談、レビュー etc.）から選びます。数回実施して、次のスプリントへの気持ちの切り替えと、メンバに対する尊敬・感謝の雰囲気づくりができているなと感じています。


### 期待値を合わせる

メンバが増えたら、必ず**ワーキングアグリーメントとインセプションデッキの見直し**を行いました。
既存のメンバとも再度認識を合わせ、古いものはアップデートします。

また、[**デリゲーションポーカー**](https://buildersbox.corp-sansan.com/entry/2019/12/12/110000)もやってみました。「スプリントバックログの作成」について、他人へ譲渡できるレベルをAsIsとToBeそれぞれ１～７の中から選び、なぜそれを選んだか共有します。
ただ、POやマネージャーがいない状態で実施してしまったため、着地点が見えずもったいない時間になってしまいました。


# 考えたこと

### リーダーシップとは何か
「リーダーシップ」というと、スポーツチームの監督のように威厳があり、トップダウンでアグレッシブに物事を判断できるイメージがありました。
スクラムマスターには**サーバントリーダーシップ**が求められるとされています。主役であるメンバの成長を促し、裏方的にチームに貢献することを得意とする特性で、これは**メンバに対する愛**が無いとなかなかできないです。人間なので苦手なこともあるし、他人に関わっていくことに対して無駄に大きなエネルギーを使ってしまうこともあります。

メンバの特性を知ることも大事ですが、大事なのは自分の特性を知って強みを生かすことだと思います。
例えば。私は割と大雑把な性格で、細かい点に気が回らなかったりすることが弱みです。
一方、他人に何か言われてもストレスだと思うことがあまりなく、時に大胆な発言をすることに対しても抵抗が無い、という強みもあると思っています（それで相手に辛い思いをさせることもありますが。。）
というように分析してみると、自分なりのリーダーシップの発揮方法が見えてくるかもしれません。

### 考えることを、やめてみる
スクラムマスターになるとあれやこれやと考えることが出てきて、思い悩むことがあります。


- **気になっていることは、正直に伝える**
必要以上に進捗管理したり追求することは、メンバの主体性と信頼関係が低下する原因になります。
ただ、チームに関して気になっていることを「これ言って大丈夫かな。。？」と思い悩み遠慮していると、その雰囲気が伝わり、風通しの悪いチームになってしまいます。
スクラムマスターは率先して気になっていることを伝え（重要なことでも、くだらないことでも）、コミュニケーションする心理的安全性を引き上げるパワーを持っています。
また、伝えるときは、[**フィードバックの5段階**](https://note.com/negikojyo/n/n97e37ee52bd4)のレベル1~2（事実、主観）で留めます。

- **未来よりも、今目の前のチームのことを考える**
「部屋の中の象」という言葉があります。
    >*The elephant in the room*「部屋の中の象」 : その場にいる人が皆認識しているけれど、あえて触れることを避けている、タブーな話題や重大な問題。

    何が起こるかわからない先のことを考えても、不安が大きくなるだけです。それよりも、今既にチームが抱えている課題を可視化する事が先です。
ところが、部屋の中の象に対処することは、非常に気が重く困難です。チームの雰囲気が悪くなることもあります（ホントにすいません）。それでもチームは立ち向かうべきだし、スクラムマスターはチャレンジし、カイゼンを進めなくてはなりません。



# 今後に向けて
あまりにも勉強不足すぎて、「コイツ大丈夫か。。？」と思われることが多々あったかと思いますが、
短い間でも多くのことを経験し、成長できた期間になりました。次回スクラムマスターをやる機会があれば、今回の反省を思い出して少しでも上手く進めたいです。
エンジニア歴2か月の私が見た開発の世界～プログラミングを0から学ぶためにくじけないマインドセット～

# はじめに
 　初めまして！この度6月からエンジニアになりました齊藤と申します。
　たった今2か月間の研修を終え、来週から本配属というタイミングで記事を書いています。学部は経営学部、好きな教科は美術と音楽です。

　今回は記念すべき第1回目の投稿ということで、エンジニア完全未経験の私がこの2か月間の開発オンボーディング研修で目の当たりにした「エンジニア」という職業の世界についてお話しします。社会人1年目かつ23年しか生きていない私にとってこの世界は、自分が今まで生きていた世界とは少し違った印象を持ったからです。


この感情は飛び込みたての今だからこそ新鮮に感じるものだと思っています。
少々長くなってしまいますが、ぴちぴちのうちにしか感じられない視点をすべて、今のうちに記録しておきます。


# 記事の対象者
新卒の方
プログラミング初学者の方
プログラミングを勉強し始めたはいいものの、難しくてあきらめようかな、、、と思っている方   

# エンジニアの世界　
**1. 「混沌」だらけの世界**
**2.  独りでいたら、時間がすぐに過ぎ去る世界**


# 1.「混沌」だらけの世界
 エンジニアになった初日
**「自分がわからないことがわからな過ぎて何から手を付けていいかもわからない！ナニコレ！」**
　というのが率直な感想でした。今もそうです。


対象の記事を読んだり誰かの説明を1回聞くだけでは、それ自体の言っていることはなんとなくわかっても、その知識をその瞬間から活用するということは難しいです。プログラミングは、基本情報技術者試験で習うようなコンピュータの構造上で動いていて、すべてが繋がっています。周囲との繋がりが頭の中でリンクした瞬間に出会えて初めて「そゆことか！」と納得感をもって理解することができます。

知識の習得は難しいかもしれない、けど大丈夫！　

ここで重要なマインドセットは2つ！

- **最初は「へ～」でOK！！！！**
- **覚える必要は全くなし！調べて使いこなせるかが大事！**

最初は「へ～」でOK！！！！
-
わからなかった内容は必ず今後の学習過程で伏線回収できるからです。少しずつ色々な情報に触れ続けていけば、どこかのタイミングで再びその内容に触れるタイミングがやってきます！まずはそのタイミングを待ちわびて、いろいろな情報に触れていきましょう！


覚える必要は全くなし！調べて使いこなせるかが大事！
- 
学校のテストでは、事前に内容を理解して覚えておく必要がありました。対して大学のレポート課題では、期限までにレポートを完成させるために、その都度必要そうな資料を調べて参考にしながら作成しますよね。プログラミングもレポート同様、一つのソフトウェアを作るためにその都度調べたことを抜粋しながら自分の作品に反映させていく、みたいなことをしています。以下のプロセスを意識して学習すれば、楽勝です！

 学習プロセス
-- 
1. 内容だけ「へ～」と理解
1. 必要になったときに「そういえばそんなのやったな～」という気持ちで調べる
1.「コレ使えるんじゃない？？？」と思われる情報を抜粋
1. 自分のコードなどに反映させる

    
このプロセスを繰り返していくうちに、いろいろな知識に出会えて自ずと開発のコツがわかってくるはずです！


# 2．独りでいたら、時間がすぐに過ぎ去る世界

エンジニアの世界は、わからないことを自分だけで考えていると、瞬く間に時間が過ぎている不思議な世界です。
特に、社会人になってからプログラミングを仕事として始められる方は時間も限られているので、できるだけ短期間で学びたいと考えていることでしょう。

ここで重要なことは2つ！
- **「答えを見る」ことを恐れないこと**
- **「人に頼る」こと**

 「答えを見る」ことを恐れないこと
  - 
 　学生時代「すぐに答えを見ちゃだめだ、、」と思いながらドリルを解いた経験はありませんか？私はあります。その癖か、わからないことがあるときにどうしても今ある脳だけで解決しようと時間をかけすぎてしまうんです。
　プログラミングは先ほどもお伝えしたように「わからないことを調べて使えるか」が肝になってきます。自分で考える時間をとることも大切ですが、わからないときはインターネットの脳みそをお借りして「答えを探しに行く」というほうが、理解して前に進めるときもあるのでおすすめです！


「人に頼る」こと
 - 
 これが一番大切だと思っています。特に新卒の方には
「先輩の業務時間を削ってしまうのが申し訳なくて聞けない、、、」
「こんな初歩的な質問して大丈夫なのだろうか、、、」
と、質問へのハードルが高いととらえている方もいらっしゃるのではないでしょうか。では、あなたがもしメンターを担当する立場だったら、次のような後輩のどちらと仕事がしたいですか？

 - わからないことを一人で考えこんでいて何日も連絡がない後輩
 - 考えてみたんですがわかりません！！！とその都度潔く質問を投げかけてくる後輩
   
 前者の後輩の場合、どのようにサポートすればよいのか、今何をしているのかがわからず、ご自身の先輩に対する情報共有にも手間取ってしまいます。後者の後輩であれば、逐一進捗内容がわかるので、メンターとしての報告義務も果たせそうです。細かな報連相は、自分だけではなく相手にとっても有益であるということが分かったと思います。なので遠慮せず、ガンガン質問していきましょう！質問するだけでなく、細かな報告、連絡、相談の時間を設けてもらえるよう自らの働きかけが大事です！



# まとめ　何とかなる！
　最後にすごくざっくりした内容になってしまいますが、以上のマインドの根底にある大切なことは「何とかなる」精神だと思っています。特に新卒の方は、プログラミングだけでなく「会社」という存在に所属すること自体が初めてで、いろいろな不安が同時に発生している時期だと思います。私自身もまだまだ未熟で躓きまくっている最中ですが、一緒に入社した同期の取り組んでいる姿を見たり話を聞いたりして「みんな同じ気持ちの中頑張っているんだな～」と励まされています。いろいろ失敗できるのも新卒の特権だと思うので、いろいろなことに挑戦して経験あるのみ！！という感じで働いていけたらと思います。一緒に頑張りましょう！



# おわりに
いかがでしたでしょうか？プログラミングだけでなくブログを書くのも初めてであるため、読みにくい部分もあったと思います。最後までお読みいただきありがとうございました。ここで書いたことはあくまで個人的な2か月間の学びではありますが、エンジニアとしての道を志した方々に少しでも参考になる部分があったと思ってもらえれば嬉しいです。