OmniAICreator/Qiita-1.07M huggingface dataset:
ActiveRecordはどのタイミングで実際にクエリを実行しているのか。SQLキャッシュについて。

# はじめに
ActiveRecordのメソッドを使ってDBアクセスすることができますが
実際にDBアクセスするタイミングは、実は即時でなかったりします(遅延評価)。

この辺りの理解を深めて、よりパフォーマンスを意識したコードが書けるように整理していきたいと思います。

また、最後に、同じリクエスト、同じ呼び出しであればRailsのモデルにキャッシュされるため
実際にDBアクセスは行われないので、この辺りにも触れたいと思います。

# ActiveRecordの遅延評価
ActiveRecordクエリを作成する場合、多くの場合、コードはデータベースの即時呼び出しを実行しません。
これにより、毎回データベースにアクセスすることなく、`.where`などで複数の句を連鎖させることができます(メソッドチェーン)。

```ruby
@users = User.where(soft_destroyed_at: nil)
# DBアクセスしない
@users = @users.where(join_date: Date.today)
# このタイミングでもDBアクセスしない
@users.count
# DBアクセスする
(7.0ms) SELECT COUNT(*) FROM "users" WHERE...
```

これにはいくつかの例外があり、例えば`find`や`find_by`の句を連鎖させることはできません。つまり、このタイミングでクエリが実行されることになります。

# ActiveRecord Relations
以下のようなUser-Postsの1対多の関係があるとします。

```ruby:# app/models/user.rb
class User < ApplicationRecord
  has_many :posts
end
```

```ruby:# app/models/post.rb
class Post < ApplicationRecord
  belongs_to :user
end
```

これにより、データベースクエリを実行して関連するレコードを見つけるための便利な`user.posts`メソッドが提供されます。

Railsアプリケーション内で、以下のサンプルコードを実行したとします。
`@user.posts`ではクエリを実行せずに、`@posts.each`...、この時点でActiveRecordはデータベースクエリを実行してデータを取得します。
```ruby
  @user = User.includes(:posts).find(1)
  # DBアクセスする
  @posts = @user.posts
  # DBアクセスしない
  @posts.each do |post|
  end
  # DBアクセスする
```

実際にログでも、`@user.posts`ではクエリが実行されず、`@posts.each`の部分で、クエリが実行されていました。
```
Post Load (299.7ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`user_id` = 1
```

(ついでに)
以下のコードを実行した場合、同じリクエスト、同じ呼び出しはRailsのモデルにキャッシュされるため、2回目の`@posts.each`ではクエリは実行されません。キャッシュからデータを取り出します。
```ruby
  # @userは、User.includes(:posts).find(1)で取得
  @posts = @user.posts
  @posts.each do |post|
  end
  # DBアクセスする
  @posts.each do |post|
  end
  # DBアクセスしない
```

# ActiveRecordに関連するレコードを再度取得したいとき
ActiveRecordの`reload`をメソッドチェーンすると、キャッシュされたものを全て無視して、データベースから最新バージョンを取得するように指示させることができます。
```ruby
@user = User.find(1)
@user.posts # DBアクセスなし
@user.posts # DBアクセスなし
@user.posts.reload # DBアクセスあり => Post Load (485.5ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`user_id` = 1
@user.posts # DBアクセスなし
```

# SQL CACHE
ActiveRecordは、パフォーマンスを高速化するために実行したクエリの内部キャッシュを保持してくれます。
ただし、このキャッシュは特定のアクションに関連付けられているので注意が必要です。アクションの開始時に作成され、アクションの終了時に破棄されます。
(1つのコントローラーアクション内で同じクエリを2回実行した場合など)


Railsアプリケーション内で、以下のようなサンプルコードを実行したとします。

```ruby
User.count # ①

User.count # ②
```

実際にログを確認すると、ひとつめの呼び出しでは実際にSQLが実行されているのが分かります。
ふたつめの呼び出しでは、SQLの実行結果がすでにRailsのモデルにキャッシュされているため、実際にDBアクセスは行われず、モデルのキャッシュからデータを取得していることになります。
```ruby
  (86.0ms)  SELECT COUNT(*) FROM `users`

  CACHE  (0.7ms)  SELECT COUNT(*) FROM `users`
```

ちなみにirbなどのコンソールの場合では、SQLのキャッシュは行われないため
挙動の確認は、実際にアプリケーションを動かしてみるのがいいかと思います。
```
sample-project % rails c
Running via Spring preloader in process 49855
Loading development environment (Rails 6.0.3.6)
irb(main):001:0> User.count
   (2.8ms)  SELECT COUNT(*) FROM `users`
=> 137
irb(main):002:0> User.count
   (5.0ms)  SELECT COUNT(*) FROM `users`
=> 137
```

# まとめ
ActiveRecordは便利だが、扱いには気をつけたいです。
もし間違っている部分があれば、ご教授いただけますと幸いです。

# 参考
https://qiita.com/ykamez/items/0c81a33ec1b90219d541

https://zenn.dev/ledsun/books/700ccad6ad861d/viewer/dcdf69

https://www.honeybadger.io/blog/rails-activerecord-caching/
formatの桁数プラスマイナス、カンマとゼロ埋め（カンマと空白）全部詰め込んだ書き方（順番）

Pythonのformatで
・桁数
・プラスマイナス
・カンマ
・ゼロ埋め
・空白埋め
それぞれは分かるのだけど、全部指定したいとき、その順番にハマった。
説明よりも実例を見れば十分なのでご覧ください。
環境：Python3.7(Anaconda/Windows10)

```
f'{12345.678:+20,.6f}'
```
の結果は
```
'      +12,345.678000'
```
「.6f」は小数点以下6桁で自然だが、
「20桁」ぽいのは「カンマの前」だし
文字全部で20「文字」ということ。

ちなみに
こんな使い方が実際必要なのかは疑問だが
```
f'{12345.678:+020,.6f}'
```
は
```
'+0,000,012,345.678000'
```
0で埋めてくれた。カンマも立派な1文字扱い。
しかし、よく数えてみると「21文字」だった。
```
'+,000,012,345.678000'  # こうはならない
```
になる訳には行かないので仕方ないか・・・
【Eclipse】作成者とコミッターを設定する方法

Githubと連携する際に、Githubと連携する方法の記事は数多くありましたが、その際「作成者(Author)」や「コミッター(Committer)」がデフォルトだと使っている端末名になってしまいます。
これだと、誰がリポジトリにプッシュしたのか分からないですし、上手く連携出来ていないように思われます。
そこで、作成者とコミッターの名前をGithubで登録されているユーザー名に設定する方法を記載致します。

# 使用環境
OS:Windows10 home
Eclipse:2021-12 (4.22.0)

# 設定方法
1.「ウィンドウ」タブから「設定」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506986/474a9de7-290c-5c5e-d242-f485c17eb893.png)

2.「バージョン管理(チーム)」から「Git」のタブを選択し、「構成」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506986/ef4bf393-fbd2-facd-4a78-eaf08940dec1.png)

3.「エントリーの追加」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506986/150b47d8-e78d-b577-507d-9fff61bbfeb1.png)

4.キーに「user.email」及び「user.name」を入れ、値にGithubで登録してあるメールアドレスとアカウント名を入力。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506986/b450130d-b997-949a-8d58-ec7e5e1bbe87.png)

5.入力内容が反映されていることを確認し、「適用して閉じる」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506986/bfb0955c-a388-5c8d-51e5-459d125a3935.png)

6.Eclipseを再起動し、設定した内容が反映されていることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506986/fb5e3861-83b4-2d31-6897-b20d44f62025.png)

# まとめ
小さなことではありますが、Gitにプッシュする際の「作成者」と「コミッター」の設定について書かせていただきました。
これまでVisual Studio Codeでやってきたので、Eclipseでの操作はまだまだ慣れていませんが、引き続き使いこなせられるように努めていきたいと思います。
又、まだGithubとの連携が済まされていない方につきましては、以下の記事が大変参考になりましたので、共有致します。(2022/05/21現在)
[EclipseとGitHubの連携方法（新規プロジェクトをGitHubにプッシュするまで）](https://skill-for-it.com/eclipse_connect_github/)

# 参考文献
[eclipseのGithub連携 Githubユーザー設定](https://techcompass-tensyoku.pro/contents/technology/eclipse%E3%81%AEgithub%E9%80%A3%E6%90%BA/#toc1)
何もわからないけど、javaでwebアプリを作りたい！

SEになって４年目を迎えてしまい、何かやろうと焦っています。。。
基幹系システムしか知らないので、webアプリとか作ってみたいなと思い、綴っております。

これは僕の作業記録です。よろしくおねがいします。
Prisma プロジェクトを serverless deploy すると Error EPERM: operation not permitted エラーが発生する問題への対処

# 問題
以下の、Prisma 公式の Serverless を使った Lambda へのデプロイ方法の記事を参考にデプロイを試した。
ここで、TSプロジェクトとしてデプロイするため `serverless-plugin-typescript` を使用している。

https://www.prisma.io/docs/guides/deployment/deployment-guides/deploying-to-aws-lambda

しかし、`serverless deploy` 時に以下のエラーが発生。

```
Error EPERM: operation not permitted
```

# 対処
先ほどの公式記事で、デプロイ時に容量削減のため node_module から余計なモジュールをはじくための設定をする[項](https://www.prisma.io/docs/guides/deployment/deployment-guides/deploying-to-aws-lambda#package-pattern-in-serverlessyml)がある。
これは、`serverless.yml` に以下の項目を追加することで実現している。

```yaml
package:
  patterns:
    - '!node_modules/.prisma/client/libquery_engine-*'
    - 'node_modules/.prisma/client/libquery_engine-rhel-*'
    - '!node_modules/prisma/libquery_engine-*'
    - '!node_modules/@prisma/engines/**'
```

しかし、実はこの設定が原因でエラーになっているようだ。これは `serverless-plugin-typescript` の問題らしい。[^1]
理由はわかっていないが、この上の二つをコメントアウトすることで機能した。

```yaml
package:
  patterns:
    # - '!node_modules/.prisma/client/libquery_engine-*'
    # - 'node_modules/.prisma/client/libquery_engine-rhel-*'
    - '!node_modules/prisma/libquery_engine-*'
    - '!node_modules/@prisma/engines/**'
```

ただし、容量は大きくなってしまう...

# 容量もちゃんと削減したい

Lambda の 50MB 制約もあって、容量削減は結構大事だったりする。

https://github.com/serverless/serverless-plugin-typescript/issues/170

↑の issue でこの問題について精力的にディスカッションされているのでコメントしたところ、容量削減もできる方法を[コメント](https://github.com/serverless/serverless-plugin-typescript/issues/170#issuecomment-1132731263)で頂いた。
まだ試せていないが、うまくいくのであればこちらをお勧めする。

## 方法
まず serverless.yml に以下の項目を追加する。

```yaml
package:
  individually: true
```

そして、Prisma を使用しているすべての関数において除外パターンを設定する。

```yaml
functions: 
  function-name:
    # ...
    package:
      patterns:
        - "!node_modules/.prisma/client/libquery_engine-*"
        - "node_modules/.prisma/client/libquery_engine-rhel-*"
        - "!node_modules/prisma/libquery_engine-*"
        - "!node_modules/@prisma/engines/**"
```





[^1]: https://github.com/serverless/serverless-plugin-typescript/issues/219#issuecomment-1032602242
本気のショートカットまとめ

## ■メモ帳
- F5 時刻でる

## ■visual studio code

## ■エクスプローラー

## ■eclipse
- 「shift+ctrl+F」フォーマット整形
- 「ctrl+space」入力補完
- 「ctrl+Alt+r」リファクタリング→変数名を一気に変える事ができる
- 「ctrl+.」エラー警告に移動できる
- 「ctrl+Alt+S」ゲッター、セッターを自動で作成する事ができる

## ■Mac 
| キー 　　　　| 挙動 | 
|:-----------|:------------|
| command + ctrl + F | 拡大/縮小 |
| command + space | Spotlightの起動 |
| Shift + Command + 4 + （control） | 指定範囲のキャプチャ（controlを入れるだけでその後ctrl+Vで貼り付け可能） |

## ■Windows
未経験者がAWSプラクティショナーを取得した感想

未経験ながら今年4月にクラウドプラクティショナーを取得しました！！
これから、AWSに挑戦するぞという方に少しでもお力になればとこの記事を作成しました。

勉強期間
12月〜4月(4ヶ月）
正直、こんなにいらなかったかなというのが感想です。
私自身、今回は締め切りをつけずに自分の力に納得した段階で受けようとしたので結果として4ヶ月もかかってしまいました。
平日1時間：休日4時間ほど確保すれば未経験でも2ヶ月あれば取得できると思います！！

参考書籍
Udemyの以下のものを使って勉強しました。
【2022年版】この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（7回分455問）

試験日までにこの問題集を正答率を毎回90％以上が出る状態になるまで繰り返し行いました。

受験感想
Udemyの問題が全く同じものという形ではありませんでした。
しかし、Udemyの問題集を正答率90％まで持っていける状態になれたら問題なく答えられる内容になっているかなと個人的には感じました。
ゼロトラストのディープダイブ(10)-SSE製品理解(Netskope社)

[前回] [ゼロトラストのディープダイブ(9)-SSE製品理解(Zscaler社)](https://qiita.com/mingchun_zhao/items/7d9de25c61cea649d576)

## はじめに

今回は、Netskope社のSSEソリューションとプラットフォームから、
ゼロトラストの仕組みについて、理解を深めます。

## Netskope社のSSEソリューション

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/5892fb0e-8794-3947-2fce-284b510a50ad.png)

- Netskope Intelligent Security Service Edge(SSE)
    - Netskope Security Cloudプラットフォームに構築される
    - 可視性とリアルタイム性を持ったデータ保護と脅威防御
    - 社内/リモートワーク/デバイス/IoTから、クラウドサービス/Webサイト/プライベートアプリへのアクセスを保護

## Netskope Security Cloudプラットフォームの構成図
※ 引用元: [The Netskope Cloud Security Platform](https://www.netskope.com/jp/platform)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/c91ba410-b891-07ee-0427-eec3c6a48dd1.png)

## Netskope SSEの特徴

- 統合性
    - SSEの4つのコア機能を一元的に提供
        - 各種セキュリティ機能をクラウドに統合・集約
        - コア機能に加えその他ユニークな機能を統合
    - ネットワーク・セキュリティ機能の統合
        - SSEとSD-WANを結合したSASEの実現
        - SD-WAN連携で拠点間の通信をゼロトラスト化
- DLP/データ保護機能
    - DLP(Data Loss Prevention)とは
        - 情報漏えいを防ぐことを目的とするセキュリティツール/システム
        - CASBで培った技術を進化させたアプリ・データの保護
        - 詳細なデータ可視化と分析機能
        - Netskopeで分類したデータラベルをBOXとシームレスに連携
- 高速なインフラ
    - 自社構築のインフラ基盤
        - 国内3か所のデータセンターで運用
    - パブリッククラウド等を利用せず、全て独自のデータセンター上で自社運用
    - SSEソリューションとして大規模なピアリング数
- ゼロトラスト技術と連携
    - マルチベンダー連携によりゼロトラストを実現
    - ユーザー・デバイスに基づいたゼロトラスト対策
    - EDR(Endpoint Detection and Response)連携により、デバイス脅威・リスクに応じたアクセス保護
        - EDRとは、コンピュータシステムのエンドポイント(端末)において脅威を継続的に監視し保護する技術
        - CrowdStrikeが、リアルタイムに端末の脅威スコアを計算
        - Netskopeで、脅威スコアに応じアダプティブな制御を実現
- IDaaS技術と連携
    - Okta等IDaaSと連携し、ユーザー・グループ情報を同期
    - 端末へのエージェント導入を簡素化

## NetSkopeのエコシステム

- Okta
    - 統合認証基盤サービスで、以下機能をクラウドで提供
        - SSO(シングルサインオン)
        - 多要素認証
        - ライフサイクル管理
        - ユニバーサルディレクトリ
- CrowdStrike
    - クラウドに収集された端末の振る舞いログを監視
    - 標的型攻撃をリアルタイムに判断・通知
    - 従来のマルウェア対策では検知できない攻撃を速やかに検知/対処
- Box
    - ストレージ容量が無制限かつセキュアに利用可能なクラウドストレージ
    - 高いセキュリティとユーザビリティを両立
    - データアップロードやダウンロードなど操作内容を克明に記録
- Splunk
    - あらゆる機器を対象にした総合的なログプラットフォーム
    - 取り込まれたデータを解析、分析し、洞察を得る事が可能
    - Netskopeのログ情報をCIMに準拠した形式で取り込む
        - CIM(Common Information Model)とは、情報共通化標準のこと
        - 異なるソースのログを表示できるようにあらかじめ定義されたSplunkが提供する独自のデータモデル
- Exabeam
    - 標的型攻撃や内部不正に見られる異常な振る舞いを検出/可視化
    - 新たな脅威を検知可能な次世代SIEMのUEBA(User and Entity Behavior Analytics)ソリューション

## Netskopeセキュリティソリューションの機能

- 安全なクラウドアクセス制御
- クラウド暗号化
- データ漏洩防止(DLP)
- SSL/TLSインスペクション
    - SSLインスペクションとは、クライアントとサーバ間の、SSL暗号化されたインターネット通信を傍受し、検証すること
    - 暗号化されたWebトラフィックとクラウドサービスに対し、以下を確認/検査
        - データ盗難がないか
        - マルウェアがないか
        - 高度な脅威がないか
            - クラウドフィッシング
            - ペイロードホスティングなど
- サードパーティのリスク監視
    - Netskope Risk Insightsを使用し、SaaS/IaaS/クラウドサービスの使用状況を監視
- 脅威防御
    - クラウドサービスとWebトラフィックに潜む脅威を防止/検出
- ウェブコンテンツのフィルタリング
    - アクティブなウェブサイトの各種カテゴリに対し、Webコンテンツフィルタリングを提供
 
## おわりに
Netskope社が提供するSSEソリューションの仕組みを理解しました。
次回は、McAfee Enterprise社のSSEソリューションを勉強します。
お楽しみに。

##### [次回] [ゼロトラストのディープダイブ(11(最終回))-SSE製品理解(McAfee Enterprise社)](https://qiita.com/mingchun_zhao/items/3a639eec506e74bb6385)
ダブルポインタによる動的メモリの確保

# 目的
ダブルポインタについて、理解を深める。

# 内容
- ポインタの概要
    - メモリのアドレスを操作するものである
    - ポインタにおいて、＊ありと＊なしの例を示す
        - ＊pi：piが指している先のアドレス
        - pi：pi自身のアドレス
- ダブルポインタの概要
  - ポインタへのポインタであり、シングルポインタの中身にアクセスするものである
  - シングルポインタの指す動的メモリにアクセスできることにより、シングルポインタを書きかえて、メモリの変更を行う手間を省くことができる

ダブルポインタによる動的メモリを確保する関数の例を下記に示す。
- **arr：*arrのポインタ
- *arr：int型のポインタであり、アドレスを指す
- malloc:int型のポインタでキャストした、int型の大きさ（4バイト）×サイズ分のメモリの先頭アドレスを返す

```
#include <stdio.h>
#include <stdlib.h>

void* allocateArray(int** arr, int size, int value){
    *arr = (int*)malloc(size * sizeof(int));
    if(*arr != NULL){
        for(int i = 0; i < size; i++){
            *(*arr+i) = value;
            printf("%d\n", **arr);
        }
    }
}

int main(){
    int* vector = NULL;
    allocateArray(&vector, 5, 45);
    free(vector);
    return 0;
}
```

プログラムの流れを説明する。
- メイン関数
    1. vectorポインタを定義
    2. vectorポインタのアドレス,size,valueを引数にもつallocateArray関数を呼び出す
    3. vectorポインタの解放 
- allocateArray関数
    1. arrポインタにmallocで確保した動的メモリの先頭アドレスを代入
    2. arrポインタの指す先がNULLでない場合、(arrポインタ＋i)へのポインタにvalueを代入する
    3. arrポインタへのポインタを出力する
    4. iがsizeと同じになるまで2,3を実行する

各ポインタの関係性を表1に示す。
vectorポインタは自身のアドレスを渡すことにより、mallocの先頭アドレスにアクセスできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1516552/5d3a0e1f-0b81-691f-2c3e-457f74892564.png)

# 所感
シングルポインタにポインタをつけること（ダブルポインタにすること）により、メモリを確保したシングルポインタにアクセスできることは、便利だと感じた。

## 参照
詳説Cポインタ　P73,74
【大事！】GitHubアカウントで2段階認証を有効化する

# 本記事の内容

- Git Hubアカウントで2段階認証を設定する。

ID/PASS認証だけだと、「何かあったらどうしよう・・」等セキュリティーに不安に感じる覚えることもあり、GitHubアカウントへ2段階認証設定を行ってみました。
セキュリティー対策やって損は無いと思いますので、本手順を参考に実施頂ければと思います。

# 実施環境
- Windows 10
- Chrome

# 手順の流れ
1. GitHubアカウントを2段階認証設定にする
2. 2段階認証でのログインを確認する


## 1.GitHubアカウントを2段階認証設定にする

GitHubのサイトにログインしマイページを表示する。
https://github.com/
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/f84a5bff-1180-4a00-50a3-0df1eec4bfcd.png)

右上のメニューから「Settings」をクリックする。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/7d29e92d-9e16-d32d-c1b3-1af9e57cca80.png)

「Password and authentication」をクリックする。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/9423e2d1-3d4c-d639-1c92-c0a3fa3179f6.png)

「Enable two-factor authentication」をクリックする。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/abf04351-cbac-5383-8630-18c46f8cd968.png)

「Set up using an app」を選択した状態で、「Continue」をクリックする。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/c1ca388b-b214-b9e2-aab8-cf8ce8155022.png)

スマートフォンの認証アプリを用いてバーコードを読み取り、表示されたコードをブラウザーに入力する。
GoogleやMicrosoftの等使えそうです。
私は普段から使っている「Google Authenticator」を利用することにしました。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/33d92c9a-ab54-47ab-7986-1593f9548c0f.png)

「Download」をクリックし、リカバリーコードのダウンロードを行う。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/9d29b1d0-672b-4f99-4ac5-db63b2970395.png)

「I have saved my recovery codes」をクリックする。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/cf715e49-3d14-6428-2792-9e2eede46af3.png)

「Done」をクリックして、2段階認証の設定は完了。
紙吹雪が落ちてきた祝福されました。笑
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/71cb1b0c-657a-5d74-b531-e4cf4a9a8be7.png)
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/20de2dbd-0e00-ee5f-8ab4-22f922727a01.png)

以上で、設定は完了。

次に右上のメニューからサインアウトを行い、2段階認証でのログインを確認をしてみます。

## 2.2段階認証でのログインを確認する

ログイン画面にて「Sing in」をクリックする。
https://github.com/
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/cb18900b-2ed8-4abc-fa60-41462207a83b.png)

ID,PASSを入力し、「Sing in」をクリックする。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/753c063e-6c59-84e3-63bc-6374d2e2b60e.png)
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/6e4b96ac-0d84-a879-a0d1-fa61b4f802b2.png)

スマートフォンの認証アプリを開き表示された認証コードをブラウザーに入力する。
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/9b8e8582-fd31-8e7b-aab1-88a4899001b6.png)

入力すると「Verifying...」となり認証される
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/b872c2f8-a1bf-1da3-2338-aa17592e40ba.png)

2段階認証でのログインが実行できた。
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/bec9156c-891e-c9f1-6fbb-021673d2cd90.png)

手順は以上です。

これでアカウントが乗っ取られる可能性が限りなく低くなったかと思います！
az-140用メモ

az-140用メモ

初めての用語

RDPショートパス　…　UDPでゲートウェイをバイパスし、セッションホストに直接接続

MS-Learn
https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-140

上記URLより出題内容
Azure Virtual Desktop のアーキテクチャを計画する (10 - 15%)
Azure Virtual Desktop のインフラストラクチャを実装する (25 - 30%)
アクセスとセキュリティを管理する (10 - 15%)
ユーザー環境とアプリを管理する (20 - 25%)
Azure Virtual Desktop インフラストラクチャの監視と保守 (20 - 25%)

Azure Virtual Desktopのユースケース
・どこからでも作業できる
・短期の労働者や請負・パートの社員
・使用できるアプリケーションを制限する

Azure Virtual Desktopのユースケースではないこと
・クラウドなのでオフラインはNG

## Azure Virtual Desktop のアーキテクチャを計画する
・ハブスポークアーキテクチャでの実装
　→Azure Active Directory Domain Serviceのデプロイとハブと仮想ネットワークにピアリングを作成する

パフォーマンスに問題があったときに対応する
・ホストプールの負荷分散
https://docs.microsoft.com/ja-jp/azure/virtual-desktop/host-pool-load-balancing
→幅優先と深さ優先について理解する
仮想マシンのサイズ設定のガイドライン
https://docs.microsoft.com/ja-jp/windows-server/remote/remote-desktop-services/virtual-machine-recs?context=%2Fazure%2Fvirtual-desktop%2Fcontext%2Fcontext
帯域幅
https://docs.microsoft.com/ja-jp/azure/virtual-desktop/rdp-bandwidth
ドレインモードについて
https://docs.microsoft.com/ja-jp/azure/virtual-desktop/drain-mode
→ドレイン モードを使用するとセッション ホストが分離され、新しいユーザー セッションを受け入れない。
ホストプールタイプ
・共有を使用　　…　マルチセッションデスクトップ
・共有と開発系　…　単一セッションデスクトップ


### ストレージの実装
FSLogix プロファイル コンテナーと Azure のファイル
https://docs.microsoft.com/ja-jp/azure/virtual-desktop/fslogix-containers-azure-files
・トラフィックが外に出ないためにはプライベートDNSゾーンを作成し、ストレージアカウントのプライベートエンドポイントを作成する。

Azure Netappのボリューム作成手順
・Azure Netapp Fileアカウントを作成（Azureポータルからできる）
・容量プールの作成
・AD接続に参加
・新しいボリュームの作成
・アクセスパラメータの構成（プロトコルとか）

ストレージアカウントのAD参加手順
・アクティブディレクトリ認証を有効にする
・共有レベルのアクセス許可を有効にする
・ディレクトリ、ファイルレベルの権限を割り当てる
・アクティブディレクトリ資格情報を使ってファイル共有をマウントする

## ユーザー環境とアプリを管理する

プリンタの登録
ユニバーサルプリントポータルを使用したプリンターの共有手順
https://docs.microsoft.com/ja-jp/universal-print/portal/share-printers
コネクタを設定
コネクタを使用してプリンタを登録
プリンタにユーザーを追加して（権限は自動）プリンタを共有する
プリンタをセッションホストに追加する


MSIXアプリケーションのデプロイ手順（Azureファイル共有を使用）
・証明書の準備と作成　…　自己署名証明書は内部とテストで使用
・MSIXパッケージ化ツールでパッケージを準備
・MSIX管理ツールでVHDX（仮想ハードドライブ）ディスクに展開
・セッションホストにAzureファイル共有の権限（ストレージファイルデータSMB共有共同作成者）を付与
・VHDX（仮想ハードドライブ）ディスクにNTFSのアクセス許可を割り当てAzureファイル共有にファイルをアップロード
・セッションホストに証明書をインストール
・MSIXパッケージをホストプールに登録する
・アプリケーションをアプリケーショングループに割り当てる

# 監視と保守

既存の知識でＯＫ
[log] 2022/05 Twitter API の申請手順 + API キー発行

# はじめに
今さらかもしれないけど Twitter API を使ったことがないので、申請してみることにした。

申請方法を検索してみたら、申請するときに理由をいろいろ書かないといけないという情報があって不安になったけど、やってみたら簡単にできた。

以下を参考にさせていただきました。

https://toxublog.com/blog/twitter_api_apply/

# Twitterアカウント作成
最初にアカウントがなかったので作成した。
今後、利用していこうと思う。

https://twitter.com/donraqqq

# APIの申請

## 1. Twitterにログインした状態で↓にアクセス。
https://developer.twitter.com/en/apps/

## 2. 右上のボタンをクリック！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273897/cab9359c-9292-d553-d8f7-d5e9aed0ac76.png)

## 3. 電話番号が未登録だと言われてしまったので登録！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273897/d9c6c979-5d24-3e16-d6f5-ce0fbe4d27e6.png)

## 4. 登録したら↓のようになるので、必要事項を入力！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273897/84d043ae-8d99-e4be-2f3a-346b98c6261a.png)
↓入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273897/ecf57aa0-be59-2871-6191-98cf6c32cb80.png)

## 5. ↓の画面が出るので同意！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273897/b933d878-877c-4784-833e-ee102b923421.png)

## 6. メールが飛ぶので、メールを確認！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273897/559a7d00-3ad0-357a-a0ed-4261919e7f20.png)

## 7. メールについているボタンをクリック！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273897/014e9e00-49f5-ce11-07ff-a9a044a64ca2.png)

## 8. ここまでで、申請は完了！
ダッシュボードの画面に遷移するので、Create！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273897/593803ee-b688-f6e8-637b-3d9d83979a3e.png)

## 9. 名前を付けてnext！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273897/04d7862b-0012-ae0e-cac1-a583f142bfb7.png)

## 10. 何に使うのかを選択してnext！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273897/fb6a2bbe-1587-dc40-969e-5fa87587a53c.png)

## 11. 説明を書いてnext！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273897/25da9733-b70b-7ff6-bbfe-882d5b24221b.png)

## 12. Appの名称を付けてnext！
※グローバルな名称のようで、同じ名前があるとエラーになる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273897/c7c7e6ea-c91c-218a-ede6-c1a6e8106a1f.png)

## 13. API Keyなどが発行されて完了！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273897/5849acbf-fd48-32bd-e7da-724c2387350c.png)

以上です。
Docker-compose3でnode.js&mongodb&nginxの環境を整える

# はじめに
　これはある記事を参考にnode.jsとmongodbとnginxのDocker環境をcomposeでめっちゃお手軽に作ったろ、とか思ったらエラーしたため案外悪戦苦闘してしまった人のお話です。
　そのため、ほとんど内容は書かず、下に貼ってあるサイトに丸投げします。
　ただ一点、エラーの発生する場所だけ書きますのであらかじめご理解を。

(この記事を書いてるEchizenって人なんですが、一応何かしら言っといたほうがいいのかしらん？)

[参考]

https://zenn.dev/cizneeh/articles/nginx-node-mongo-docker-example#docker-compose.yml
# 環境
**22/05/21**
・CentOS7
・Docker 1.13.1
・Docker-compose 1.18.0
# docker-compose.yml
　参考のサイトを進めていけば適当なディレクトリ構成でnode.jsとmongodbとnginxが使える環境が作れるはずなのですが、最後の最後に書かれているdocker-compose.ymlはコピ＆ペするだけではエラーが発生してしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2647158/a56f78ec-3c73-2bf1-fe6c-2e87eb1ef953.png)

　　　　↑これです
　僕がエラーを出してしまった場所はインデントとバージョンの指定のようです。
　よって以下のように書き換えます。

```
version: '3'

services:
   nginx:
     build: ./nginx
     container_name: nginx
     depends_on:
       - server
     ports:
       - 8080:80

   server:
     build: ./server
     container_name: server
     depends_on:
       - mongo

   mongo:
     image: mongo
     container_name: mongo
     environment:
       MONGO_INITDB_DATABASE: admin
     volumes:
       - ./mongo/init.js:/docker-entrypoint-initdb.d/init.js:ro
       - ./mongo/mongo-data:/data/db
     # Start mongo with authentication enabled
     command: [mongod, --auth]
```

　変更点は先ほど言った通り、ヘッドに書き加えたのと、インデントを変えたのです。

# 最後に
　どうしてコピペしても出来なかったんだろう？？？
　記事を書く際にインデントが変更されてしまっていたのか、それともDocker-composeのバージョンが違ったのか。まぁそれは僕にはわからないことです。
　ともかく、こうすれば少なくともnode.jsとmongodbとnginxの環境が整えられると思います。さーこれでnode.jsでサーバーアプリを作れるぞー！
ECRへのPUSHをトリガーにECSのローリングアップデートを行う

# ■Lambda

ローリングアップデートを行うための処理を作成

### ▼Lamdaを作成する際の選択値

| 項目 | 値 |
| ---       | --- |
| name | test ※仮でtestとします |
| 関数の作成 | 一から作成 |
| ランタイム | Node.js 16.x |

### ▼コード

:::note alert
Node.js での現時点でのSDKサポートは v2 になります
※ 最新版を使用したい場合は自身でデプロイを行う必要があります

https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html
:::

```index.js
const aws = require('aws-sdk')

// async は付けないでください
exports.handler = (event, context) => {
  const ecs = new aws.ECS({region: event.region});

  // 環境変数は「Lambda」の「設定」に保存します
  // 「forceNewDeployment」はイメージに更新がある場合に限定するなら不要
  ecs.updateService({
    cluster: process.env.CLUSTER,
    service: process.env.SERVICE,
    forceNewDeployment: true
  }, (err, data) => {
    if (err) {
      console.log(err);
    } else {
      context.succeed('succeed');
    }
  });
};
```

### ▼設定 > アクセス権限

:::note warn
**作成時に「ロール権限」を自動生成している前提となります。**
※リンクからIAMに遷移が出来ます
※ログの権限は自動生成時に付与されています
:::

下記をインラインポリシーで追加します。

| 項目 | 値 |
| --- | --- |
| サービス | Elastic Container Service |
| アクション | UpdateService |
| リーソース | すべて |

:::note info
ログはCloudWatchのロググループ に「/aws/lambda/【Lambdaの関数名】」で生成されます
:::

### ▼設定 > 環境変数

| 項目 | 値 |
| --- | --- |
| CLUSTER | ECSのクラスター名 |
| SERVICE | ECSのクラスターに所属するサービス名 |

# ■Amazon EventBridge

ルールを新規に作成します

<table>
  <tr><td>ルールの詳細</td><td>ルールタイプ</td><td>イベントパターンを持つルール</td></tr>
  <tr><td>イベントソース</td><td>イベントソース</td><td>AWS イベントまたは EventBridge パートナーイベント</td></tr>
  <tr><td rowspan="7">イベントパターン</td><td>イベントソース</td><td>AWSのサービス</td></tr>
  <tr><td>AWS のサービス</td><td>Elastic Container Registry(ECR)</td></tr>
  <tr><td>イベントタイプ</td><td>ECR Image Action</td></tr>
  <tr><td>特定のアクションタイプ</td><td>PUSH</td></tr>
  <tr><td>特定の結果</td><td>SUCCESS</td></tr>
  <tr><td>特定のリポジトリ</td><td>【作成リポジトリ】</td></tr>
  <tr><td>特定のイメージタグ</td><td>【トリガーとしたいタグ名】</td></tr>
  <tr><td rowspan="3">ターゲットを選択</td><td>ターゲットタイプ</td><td>AWSのサービス</td></tr>
  <tr><td>ターゲットを選択</td><td>Lambda関数</td></tr>
  <tr><td>機能</td><td>【Lambdaで作成したローリングアップデートを行う関数名を選択】</td></tr>
</table>

# ■テスト

上記の「Lambda」と「Amazon EventBridge」で設定は完了となります。
ECRの該当リポジトリに設定したタグを push するとローリングアップデートが実施されます。

:::note info
既存イメージに「EventBridge」のトリガーとなる「タグ」を追加した場合もローリングアップデートが実施されます。
例えば、トリガーとなるタグを「latest」とした場合、「staging」タグが付与されているイメージに「latest」を追加してもローリングアップデートが実施されます。
:::

# ■関連記事
https://qiita.com/error484/items/fa9952ecd1e98706884f
【JUnit】mockwebserverのtakeRequestでテストが止まる

# 概要
JUnitを書いていて、WebClientのUTを記載した際、takeRequestで実行内容を取得しようとするところでテストが止まる事象が起きた。同じとこで詰まってる人いたらのため記載。

以下のようにぐるぐるなって進まない。
![テストファイル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153118/3b0fa0bc-e7e4-5514-981a-760712951847.png)

https://square.github.io/okhttp/3.x/mockwebserver/index.html?okhttp3/mockwebserver/MockWebServer.html

# 原因
原因説明のために以下にソースを記載する。
### テストソース
```
    MockWebServer mockServer = new MockWebServer();
    mockServer.start();
    baseUrl = String.format("http://localhost:%s", mockServer.getPort());
    mockServer.enqueue(
        new MockResponse().setResponseCode(204).addHeader("Content-Type", "application/json"));
    // ソース実行
    repository.request([リクエストがあれば]);
    // ここの処理で止まる(リクエスト待ち状態になる)
    final RecordedRequest recordedRequest = mockServer.takeRequest();
```

### テスト対象ソース
以下のようにエラーハンドリングでMono系を返すため、Mono<Void>を使用していた。これが原因。
```
public Mono<Void> request(@NonNull final TestRequest request) {
    return webClient.post().uri(
        uriBuilder -> uriBuilder.path([PATH]).build())
        .body(BodyInserters.fromValue(request))
        .accept(MediaType.APPLICATION_JSON)
        .retrieve()
        .onStatus(HttpStatus::is4xxClientError, clientResponse ->
            clientResponse.bodyToMono(String.class)
                .flatMap(error -> Mono.error(new Exception(
                    "エラーが発生しました: " + error)))
        )
        .bodyToMono(requestVoidType);
}
```

# 解決策
最後にblockしないとテスト内でリクエストがされていない状態になっていたのでテストソースの方でblockを追加したところ通るようになった。
```
// before
repository.request([リクエストがあれば]);

//after
repository.request([リクエストがあれば]).block();
```
【python】playwrightでログイン処理省略する方法


# 1. やりたいこと
Webブラウザの評価を行うとき、毎回確認ログイン処理するのは、億劫ですしテストの実行が遅くなる可能性があります。これを防ぐために、既存の認証状態を新しいブラウザコンテキストで再利用して、ログイン処理を省略できるようにします。

# 2.　環境
playwrighとpytestが入っている環境を用意します。環境構築方法は、[別記事][link-9-1]に記載しています。
　・macOS 12.4(monterey)
　・Python 3.7.6
　・pip 22.1
　・pytest 6.2.5
　・playwright 1.16.2

| フレームワーク|コンテンツ|
|:----------- |:------------|
|[playwright][link-1-1]| マイクロソフト社が実行ブラウザを自動化する|
|[pytest][link-1-2]|Pythonで、このプログラムをする|

# 3. 実現方法
playwrightには、ログインを省略する直接的な機能はありませんので少しばかり工夫が必要です。
具体的には、下記のように一度ログインし、認証状態を再利用することを組み合わせて、ログイン処理を省略できるようにします。
(1) テストの開始前にUIを介してログインし、認証状態を取得します。
(2) 取得した認証情報をローカルに保存します。
(3) 各テスト関数で認証情報を読み込ませて、テスト実施する。

# 4. 環境設定
rootフォルダの直下に実行ファイルと認証情報を保管するためのjsonファイルを作成します。
※ 実行ファイルのファイル名は、pytestの仕様上「test_xxx.py」としてください。
>root
> |- state.json
> |－ test_login.py
> |－ test_001.py


# 5. コード
実行ファイルに下記のようなプログラムを書きます。state.jsonは、記述なしで構いません。

```ruby:test_login.py
import pytest
from playwright.sync_api import Playwright, sync_playwright
# ログイン関数
def test_login(playwright):
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()
    page.goto(ログインページ)
    page.fill(ユーザーフィールド, UserID)
    page.fill(パスワードフィールド, Password)
    page.click(ログインボタン)
    context.storage_state(path="state.json") #認証情報をローカルに保存
```
```ruby:test_001.py
import pytest
from playwright.sync_api import Playwright, sync_playwright

# ログイン後のテスト関数
def test_001(playwright):
    browser = playwright.chromium.launch(headless=False)
    context = browser.new_context(storage_state="state.json") #ローカルに保存した認証情報を取得
    page = context.new_page()
    page.goto(ログイン後のページ)　#ログイン処理なしで、ログイン後のページに遷移

```
# 6. 実行 
ターミナルを起動後rootフォルダーに移動し、「test_login.py」でログイン処理を実行します。実行後、state.jsonに認証情報が保存されています。

```ruby:./root
pytest test_login.py
```

state.jsonに認証情報が保存された状態で、「pytest」を実施します。
```ruby:./root
pytest 
```

<dt>実行結果</dt>

ログイン処理をしないtest_001.pyの実行結果もPassedとなり、ログイン処理省略してテスト実現することができました。

![スクリーンショット 2022-05-21 10.38.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667601/b18dc826-d1ec-3084-2211-75c7724efb04.png)


# 7. 関連記事
・[【python】playwrightでE2E評価環境を作る][link-9-1]
・[【python】playwrightの実行中の操作を録画する方法][link-9-2]
・[【python】playwrightでパラメータテストする方法][link-9-3]

[link-1-1]: https://playwright.dev/
[link-1-2]: https://docs.pytest.org/
[link-2-2]: http://qiita.com/
[link-4-1]: http://www.uitestingplayground.com/
[link-9-1]: https://qiita.com/ryuusen999/items/4642cc03095e29bed0e9
[link-9-2]: https://qiita.com/ryuusen999/items/ec3b95f1c2e2aa4f5856
[link-9-3]: https://qiita.com/ryuusen999/items/4e9a1c9a16c6819e3f9c
fzfを使ってgit checkout commit-idをスムーズに行う

Gitを使った開発をしていると、特定のコミットにcheckoutすることが一日に何回もあると思います。
ブランチやタグの割り当てられていないコミットの場合、以下のような手順でコミットIDを指定する必要があり、面倒です。

1. `git log`でツリーを表示する
1. ckeckoutするコミットのコミットIDをコピーする
1. コミットIDをペーストしてcheckoutする

そこで、上の一連の流れをスムーズに行うシェル関数を、`fzf`を使用して実装してみました。

# 前提
`fzf`がインストールされていることを前提とします。
`fzf`そのもの及びインストール方法については本家をご参照ください。

https://github.com/junegunn/fzf

# 実装

```bash
# fco - checkout git commit
fco() {
  local commit
  commit=$(git log --graph --color=always --remotes --branches \
               --format="%C(auto)%h%d %s %C(white)%C(bold)%cr" "$@" |
           fzf --ansi --no-sort --reverse --tiebreak=index --bind=ctrl-s:toggle-sort |
           grep -o '[a-f0-9]\{7\}') &&
           git checkout $commit
}
```

関数名や`git log`と`fzf`のオプションはお好みで変更してください。

上の実装だと以下のようになります。

![fck.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432674/e1451f05-9067-6c93-5ccb-693d695bec63.gif)


# 参考にした記事
https://qiita.com/kamykn/items/aa9920f07487559c0c7e

今回の実装は参考記事様での`fbr`と`fshow`をおおいに参考にしています。
アクセス権限変更（Linux）chmod

# chmodを使用したファイルやディレクトリの権限変更
※AWSのCloud9のターミナルを使用
## 1.権限の確認
カレントディレクトリ内のファイルやディレクトリの権限を確認する場合
```
ls -l
```
コマンドを入力すると
```
drwxrwxr-x 4 ec2-user ec2-user 106 May  1 10:52 sample
-rw-r--r-- 1 ec2-user ec2-user 569 Apr 12 03:16 sample.txt
```
といった文字列が表示されます。

上段の
```
drwxrwxr-x 4 ec2-user ec2-user 106 May  1 10:52 sample
```
について説明します。

#### ① 一番右の「sample」の部分
配下に存在するのファイルやディレクトリ名です。

#### ② drwxrwxr-x
###### ・最初の「d」の部分
|  種別  |  意味  |
| ----- | ---- |
| - | ファイル |
|  d  |  ディレクトリ  |
|  l  |  リンク  |

###### ・以下のrwxrwxr-x
まず、「rwx、rwx、r-x」と３文字ずつ分けて考えます。
　　　最初の3文字のrwxはファイルやディレクトリの所有者の権限
　　　次のrwxはグループの権限
　　　最後のr-xはその他のユーザーの権限
となります。
「r」「w」「x」「-」の意味は以下の通り
|  種別  |  意味  |
| ----- | ---- |
| r | 読み取り |
|  w  |  書き込み  |
|  x  |  実行  |
|  -  |  許可なし  |

例：「r-x」は読み取りと実行のみ可能、書き込みはできません。

#### ③ drwxrwxr-xの右の「4」
ハードリンク数

#### ④ ec2-user ec2-user
ec2-userが2つあってわかりづらいですが、
最初の「ec2-user」は所有者名
右の「ec2-user」はグループ名

#### ⑤ May  1 10:52
更新日時です。

上記説明を組み合わせると、
```
drwxrwxr-x 4 ec2-user ec2-user 106 May  1 10:52 sample
```
は、「sample」というディレクトリで、所有者は「ec2-user」、所有グループは「ec2-user」、所有者と所有グループは読み取り、書き込み、実行すべて許可、その他のユーザーは読み取り、実行のみ許可、更新日時は5月1日10:52となります。

## 2.権限変更
### 「chmod」を使用した権限変更
※chmodは change modeの略です
#### ① コマンド
```
$ chmod 751 sample
```
というコマンドを使用します(変えたい権限によって数値が変わります)。
#### ② 数値について
上記の「751」は「7」「5」「1」と分けて考えます。
最初の「7」は所有者の権限、次の「5」はグループの権限、最後の「1」はその他のユーザーの権限です。

|  権限  |  数字  |
| ----- | ---- |
| r | 4 |
|  w  |  2  |
|  x  |  1  |

この表を参考に、与えたい権限の数字を足して表します。
例えば、読み取りと実行のみ与える場合は
```
4(r) + 1(1) = 5
```
となります。
まとめると
|  権限  |  数値  |
| ----- | ---- |
| --- | 0 |
|  --x  |  1  |
|  -w-  |  2  |
| -wr | 3 |
|  r--  |  4  |
|  r-x  |  5  |
| rw- | 6 |
|  rwx  |  7  |

となります。

この数字を組み合わせ、sampleというディレクトリについて、所有者には全ての権限(7)、グループには読み込みと実行(5)、その他のユーザーには実行のみ(1)を与えたい場合は
```
chmod 751 sample
```
とコマンドを入力します。

その後、再度
```
ls -l
```
を実行し、権限を確認しましょう。
【5分でできる】Qiita API v2で限定共有記事含めて自分の記事をコマンドラインで取得してみた


## はじめに
(自分が知らないだけかもですが)現在のQiitaでは、限定共有記事を検索できないようなので、手始めに自分の記事をQiita APIで取得できるか検証してみました。

## 方法
Qiitaをひらき、プロフィールの**設定**を選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/1ddb360a-b0bc-a482-af8f-4094b9d4fad5.png)

**アプリケーション**を選択し、**個人用アクセストークン**から**新しくトークンを発行する**を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/2f11ccd1-faf2-6d12-acf8-6a3ec20b41c1.png)

以下を記載または選択
- アクセストークンの説明
- スコープ
    - 自分の記事を取得するだけであれば、**read_qiita**権限があればOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/e70e7c64-6f81-9124-c504-f289341a89e4.png)

個人用アクセストークンを保存

![Qiita - Google Chrome 2022-05-21 08.39.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/d138e23a-1af8-b5f8-c612-1e2fd473c312.png)

## 検証
自分の記事を取得してみる
限定共有記事も取得できるので、それら含めて自分の記事を取得したい人に使えそう

```bash
curl -H "Authorization: Bearer <個人用アクセストークン>" https://qiita.com/api/v2/authenticated_user/items
```

## 参考

- https://qiita.com/api/v2/docs#%E6%8A%95%E7%A8%BF
    - 投稿
    - 認証認可
STM32 内蔵ブートローダの起動

# はじめに
ユーザコード（アプリケーション）からSTM32の内蔵ブートローダを起動する必要があり、その調査をしたので忘備のためにまとめました。
内蔵ブートローダは、生産時にSTマイクロエレクトロニクス社によってプログラムされているそうです。

# 使用機器
|メーカ|型格|
|:-:|:-:|
|STマイクロエレクトロニクス社|NUCLEO-L476RG|
|STマイクロエレクトロニクス社|STM32CubeIDE|

# ブート設定
ブートモードの選択は、オプションバイトでBOOT0ピンおよびnBOOT1ビットによって3種類から選択することができます。
|BOOT1|BOOT0|ブートモード|
|:-:|:-:|:-:|
|x|0|メインフラッシュメモリ|
|0|1|システムメモリ|
|1|1|内蔵SRAM1|

NUCLEO-L476RGではBOOT0がLOWになっているのでブートモードはメインフラッシュメモリが選択されています。
アプリケーションノート（AN2606）を読むとBOOT0がLOWであっても有効なコードが含まれていなければ内蔵ブートローダにジャンプできるとありましたが、メインフラッシュメモリの内容を全て消去したくなかったのでユーザコードから内蔵ブートローダにジャンプする方法を選択しました。

# 内蔵ブートローダの配置
内蔵ブートローダは下表の通り配置されており、下表のRAMを使用するようになっているようです。
||アドレス|メモ|
|:-:|:-:|:-:|
|システムメモリ|0x1FFF 0000|左記のアドレスから28KBにブートローダが格納されています|
|RAM|0x2000 0000|左記のアドレスから12KBがブートローダに使用される|

# 内蔵ブートローダへジャンプするための条件
ユーザコードから内蔵ブートローダにジャンプするには下記の準備をする必要があります。
+ 全てのペリフェラルクロックの無効化
+ 使用したPLLの無効化
+ 割り込みの無効化
+ ペンディング割り込みのクリア

# 内蔵ブートローダへのジャンプ
内蔵ブートローダの先頭にベクタテーブルがあります。ベクタテーブルの先頭にはMSP、その次にはリセットハンドラのアドレスが格納されているので、これを利用して内蔵ブートローダにジャンプします。

![ベクタテーブル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148400/ed8a017d-8354-8f74-ea49-02c06fd9df13.png)


内蔵ブートローダにジャンプするための条件を満たすのは大変なため、STM32CubeIDEが自動生成したスタートアップを変更して対応しました。

```startup_stm32l476rgtx.s
ldr ap, =_estack

/* ここで内蔵ブートローダにジャンプするかmain関数にジャンプするか判断する */
bl Loader
```
``` Loader.c
void Loader(void)
{
    uint32_t msp = *((uint32_t *)0x1FFF0000u);
    uint32_t Reset_Handler = *((uint32_t *)0x1FFF0000u + 4u);

    // 内蔵ブートローダのメインスタックポインタを設定する
    __set_MSP(msp);

    // 内蔵ブートローダのリセットハンドラにジャンプする
    ((void (*)(void))Reset_Handler)();

    while (1) {

        // 内蔵ブートローダにジャンプするのでここに来ることはない
        __asm __volatile("nop\n");
    }
}
```

# 内蔵ブートローダの起動後の対応
内蔵ブートローダが起動したら、CAN, USART, USB DFU, I2C, SPIで通信を行います。
プロトコルの詳細はアプリケーションノートに記載されています。

# 参考サイト
[ブートローダ](https://lowreal.net/2019/09/08/1)
[アプリケーションノート（AN2606）](https://www.stmcu.jp/design/document/application_note/51328/)
[アプリケーションノート（CANプロトコル）](https://www.stmcu.jp/design/document/application_note/51380/)
[アプリケーションノート（USARTプロトコル）](https://www.stmcu.jp/design/document/application_note/51313/)
[アプリケーションノート（USB DFUプロトコル）](https://www.stmcu.jp/design/document/application_note/51307/)
[アプリケーションノート（I2Cプロトコル）](https://www.stmcu.jp/design/document/application_note/51317/)
[アプリケーションノート（SPIプロトコル）](https://www.st.com/resource/en/application_note/an4286-spi-protocol-used-in-the-stm32-bootloader-stmicroelectronics.pdf)
v
python関連のアップデートコマンド

Python関連をアップデートするコマンド一覧を、忘れないように残します。

# pipのアップデート
```python:
pip install --upgrade pip
```
もしくは
```python:
python -m pip install --upgrade pip
```

# Anacondaのアップデート
anacondaの本体をアップデートする。
```python:
conda update conda -y
````
全パッケージをアップデートする。
```python:
conda update --all -y
```
pythonをアップデートする。
```python:
conda update python -y
```
不要なファイルを削除する。
```python:
conda clean --all -y
```
RSpecの"GET #show"で[:ok]のはずが[:found]となってしまった話

## 概要

request specの"GET #show"にてリクエストが成功するかテストを行なってみたところ、HTTPステータスコードが200(:ok)を期待したが、302(:found)が結果として出力された。

```bash:ターミナル
$ bundle exec rspec spec/requests/recipes_spec.rb

# ===== 省略 =====

GET #show
    レシピIDを渡してリクエストを投げたとき
      リクエストが成功する (FAILED - 1)

Failures:

  1) Recipes GET #show レシピIDを渡してリクエストを投げたとき リクエストが成功する
     Failure/Error: expect(response).to have_http_status(:ok)
       expected the response to have status code :ok (200) but it was :found (302)
     # ./spec/requests/recipes_spec.rb:33:in `block (4 levels) in <main>'

```

## 結論

`config.include Devise::Test::IntegrationHelpers, type: :request`を追加してDeviseのヘルパーを使えるようにする。

```ruby:spec/rails_helper.rb
RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods

  # ===== Deviseのヘルパーを使えるようにする設定するため、ここを追加 =====
  config.include Devise::Test::IntegrationHelpers, type: :request
  
  # ===== 省略 =====
end
```

`example`内の **`get(recipe_path(recipe.id))`よりも前** に`sign_in user`を追加する。

```ruby:spec/requests/recipes_spec.rb
RSpec.describe "Recipes", type: :request do

  # ===== 省略 =====
  
  describe "GET #show" do
    context "レシピIDを渡してリクエストを投げたとき" do
      let(:user) { create(:user) }
      let(:recipe) { create(:recipe) }
      it "リクエストが成功する" do
        sign_in user  # ===== これを追加 =====
        get(recipe_path(recipe.id))
        expect(response).to have_http_status(:ok)
      end
    end
  end
end
```

## 原因

なぜ、302(:found)が結果として出力されたのか。
それは`application_controller.rb`に記述している`authenticate_user!`が原因だった。

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :authenticate_user!
  
  # ===== 省略 =====
end

```

このメソッドが働いて"#show"にアクセスする前にログインページへリダイレクトされてしまった。
その結果、302(:found)が吐き出されたのだ。

以上です。
指摘箇所がありましたら、ご教授いただけますと幸いです。

## 参考

- [RSpecでログイン状態にする方法(sign_inヘルパー)](https://qiita.com/qp___04/items/084ded235ea109fc90fb)
- [Railsでコントローラーの単体テストコード時に「302」のエラーが出た時の対処法
](https://qiita.com/yosyosyoyoyo/items/be54d7249a7f69cecbd0)
Microsoft SC-900(Security, Compliance, and Identity Fundamentals)試験

## この記事について
・SC-900試験に合格したので、備忘録的なメモです。


## 受験した理由
・またまたMicrosoft Virtual Training Dayに参加したからです。
　こちらは2.5時間×2日の動画を見るだけで、SC-900試験を無料で受講できるという、
　超おススメセミナーです。
　MSは定期的にこういったセミナーがあるので素敵です。


・セキュリティ関連はどんな仕事するにも必須なので、ちょっと見ておくかという軽い気持ちで参加しました。




## 勉強の仕方
・セミナーで、あまりに知らないサービスが多く、ちょっと危機感を感じました。
・そのため、2週間くらいかけてちょっと勉強してみました。



### MS Learn
・まずはこれが基本ですよね。
　とはいえ触ったことがないサービスがほとんどだったので、読むだけでは合格できないと思いました。
　(もちろん、私のスキルレベルが低いことが原因です。
　 基本的にはここに書いてあることが十分理解できれば、合格できると思います）
　あと、Chromeだと動画がうまく見えなかったです。

### Udemy

・MS Learnだけでは無理だと思ったので、Udemyで問題を解くことにしました。
　購入したのはこちら。
　評価が高く、ちょうどセールで安かったのが選択理由です。　
　https://www.udemy.com/course/sc-900-exam-questions-microsoft-security-compliance-identity/

　早速テストしてみたのですが、、難しい。
　4回の演習テストがあったので、1，2回については50%も取れないありさまでした。
　
　解説がそれなりに充実しているので、何度か読み返すことで9割程度の得点をとれるようになりました。


### マイクロソフトの試験対策オンデマンド講座

・MSのページをウロウロしていたら、無料の試験対策講座があるのを見つけました。
　日本語での丁寧な説明と問題解説があり、かなりお勧めです。
　Udemyで無理やり覚えた知識を、体系的に確認することができました。
　実際の試験でも、まったく同じような問題が何問か出題されました。
　（このページ、MS Learnからは辿れないですよね？　）
・https://www.microsoft.com/ja-jp/events/top/skilling?activetab=g1%3aprimaryr4

・ただしこの講座だけでは、ちょっと合格は難しいかもしれません。
　MS Learnとの併用は必須です。


### サンプル問題

　さらにマイクロソフトのページを見ていたら、サンプル問題も見つけました。
　Udemyの問題に比べると簡単です。
　問題数も少ないので、テスト前に確認するくらいで大丈夫だと思います。
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562552/21a9ff16-b2c9-491e-0ce1-cf38db172ff6.png)



## 結果
・945点で合格しました。
・Udemyの問題に比べると、基本的な確認問題が多く、自信をもって回答できました。

## これから受験する人へ　
・英語で確認したほうが良い場合があります。
　Chromeの翻訳機能を利用したのですが、ときどき混乱しました。
　　機密ラベル、感度ラベル？
　　グローバル管理者？　admin? administrator?　など
・Udemyの問題は難しすぎます。
　合格するためであれば、7割くらいとけたら十分だと思います。
・私でも合格できました！　頑張ってください！！
Firebaseの環境構築、M1Macにて

## nodeのインストール
`brew install node`で完了！

## firebaseコマンドラインツールをインストール
`npm install -g firebase-tools`で完了！

## ログインをする
`firebase serve`をしてサイト閲覧できるかな？と思ったら、ログインしろと出た。ので指示に従う。
`firebase login`でブラウザのログイン画面に自動で遷移してログイン完了！

## functionsディレクトリでnpmをインストールする
`firebase serve`今度こそ行けるかなと思ったらなんかfunctionsで`npm install`しろとターミナルさんに言われたので実行。

## できた
`firebase serve`が実行できたのでよし！

## 参考
> Firebaseの環境構築の情報はここを見ました！
(参考：[サイトのリンクはこちらです](https://appcoding.net/firebase-install/#Nodejsnpm))

## 経緯
- 調べればすぐに出るけどまあ練習だと思って書きました
- 今後も気分次第かな？記事書くのは
【TypeScript】for (const key in obj) の型について

## はじめに

例えば、`for (const key in obj)` 内での`key`の型などについて理解できていなかったのでまとめる。

## 結論

上記の例で言うと、`key`　の型は「`Extract<keyof T, string>`」で、

`obj`のkeyの`文字列リテラルのユニオン型(String Literal Union)`　でかつ、string型のもの。という意味になる。

## 詳細

### `Extract`とは

`Extract<T,U>`：T型のプロパティでU型に代入可能なプロパティのみを残した型を構築する。

### `keyof`とは

`keyof T`：以下のようにオブジェクトのプロパティ名を抽出して `文字列リテラルのユニオン型(String Literal Union)` を取得できる。

```
type Person = {
  name: string;
  old: number;
};

type Keys = keyof Person; // "name" | "old"
```

これがわかれば、以下のようなメソッドがあった場合に`key`に入り得るのは、”name”か”old”だけ、と理解できる。

```ruby
function shallowCopy<T extends object>(obj: T): T {
  const result = {};
  for (const key in obj) {
    result[key] = obj[key];
  }
  return result;
}

const testObj = {
  name: "yamada",
  old: 15
}

shallowCopy<Person>(testObj)
```

## おわりに

`Extract`　などが絡んできて複雑そうに感じたが一つ一つ理解すれば、なにも問題なかった。

`Extract<keyof T, string>`という見た目が難しそうなだけで、内容は「`for (const key in obj)`とした場合の`key`はオブジェクトの`key`一覧の中のどれか」という当たり前のことであった。
【Rails】find_or_create_byでバリデーションをskipさせたい

# 結論
## 1.saveに `validate: false`を渡す
- `validate: false`を末尾に記載することで、バリデーションをskipできました。
- 加えて、無意味な`save`を2回走らせないように、`find_or_create_by` から `find_or_initialize_by` に修正しました。

```ruby
Model.find_or_initialize_by(name: "テスト") do |m|
  m.published_at = Time.zone.today - 1 # バリデーション対象のコード
  m.save(validate: false)  #=> バリデーションをskipさせる
end
```

# 補足
@jnchitoさんよりコメントいただきました。

## 1.new_record?メソッドを使用する
ブロックの外で`save(validate: false)`を実行します。

```rb
# この時点ではsaveしない
model = Model.find_or_initialize_by(name: "テスト") do |m|
  m.published_at = Time.zone.today - 1
end
# ここで初めてsaveする
model.save(validate: false) if model.new_record?
```



## 2.バリデーションを通さずに、カラムを直接更新する
`update_columns`を使用することで、バリデーションを通さないで更新することができます。

```rb
# !を付けて意図しないバリデーションエラーが発生したら例外を発生させる
model = Model.find_or_create_by!(name: "テスト")

if model.published_at.nil?
  # Railsのバリデーションを通さず、DB上のpublished_atカラムを直接更新する
  model.update_columns(published_at: Time.zone.today - 1)
end
```



# 背景

**目的** 
作成日よりも遅い日付のテストデータを作成したい

**現状**
「作成日よりも遅い日付は登録できない」というバリデーションを設定しているため、保存できない

**対応策**
テストデータを作成するときのみ、バリデーションをskipさせたい

# 改善前

`find_or_create_by`でテストデータを作成していたが、バリデーション設定後、エラーするようになった。

```ruby
# エラーになるコード
Model.find_or_create_by(name: "テスト") do |m|
  m.published_at = Time.zone.today - 1  # 作成日よりも遅い日付を渡すと、エラーになる。
end
```

# 調査と結果

- saveメソッドにオプションを渡すことで、skipできることがわかった。

```ruby
save(validate: false)
```

- それをブロックの最後で実行することで、skipさせることができた！

```ruby
Model.find_or_create_by(name: "テスト") do |m|
    
  # 略

  m.save(validate: false)  #=> 追加
end
```

# 参考資料

- [Active Record バリデーション - Railsガイド](https://railsguides.jp/active_record_validations.html#%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E3%82%B9%E3%82%AD%E3%83%83%E3%83%97)
Node.js x LINE Messaging APIで複数メッセージを1度に送ってみた


## はじめに
LINEの公式ドキュメントでは単一メッセージを送るサンプルコードしか記載がなかったため、複数メッセージを特定ユーザに送ることは可能かを検証してみました。

## 方法

```bash
$ npm install @line/bot-sdk
```

```test.js
const line = require('@line/bot-sdk');

const client = new line.Client({
  channelAccessToken: '<channel access token>'
});

const message = [
	  {
	      "type":"text",
	      "text":"Hello, world1"
	  },
	  {
	      "type":"text",
	      "text":"Hello, world2"
	  }
];

client.pushMessage('<to>', message)
  .then(() => {
    console.log('Success');
  })
  .catch((err) => {
    console.error('Failed', JSON.stringify(err));
  });
```

## 検証

プログラムを実行してみます。

```bash
node test.js
```

2つのメッセージが送信されることを確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/34ff0065-8463-0d02-0a2d-87ff085c36bf.png)






## 参考
https://developers.line.biz/console/channel/1657059973/basics
エンジニアよ君は99.9%の専門書を読む必要がない

今日もたくさんの記事がQiitaに並んでいるが、読むべき記事はほんの一握りだ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/3586226e-7433-5cd7-be6c-d12dcdc5f5ec.png)

たとえばJAVAエンジニアならば、PHPの記事を読む必要があるだろうか？

今日もたくさんの本が本屋に並んでいるが、本当に読むべき本はほんの一握りだ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/7ab97c85-7bf2-b33e-29e9-c182bb55eff0.png)

なんだろう、知識知識知識知識知識知識知識知識知識知識。
この世界は知識にあふれている。

知識とは世界の切り取り方である。断面の数だけ知識が増える。知識は増殖し、印刷され、世の中にばらまかれる。そうして選別に選別を重ねた書籍というスタイルの情報でさえ、99.9%は必要のない情報だ。

知識マニアならいざしらず、僕はたくさんの知識なんてほしくない。頭がクラクラする。難しいことはあまり言わないでほしい。より簡単な世界で生きていたい。

- クリーンアーキテクチャ？ なにそれ。よく分からないものはとりあえず要らない。
- ドメイク駆動開発？「適切名前付け」の数語で表現できないだろうか。
- オブジェクト指向？ オブジェクト指向を知らなくてもオブジェクト指向言語は書ける。

すごい知識はすごい人達に任せておけば良い。

それよりも僕が興味を持つのは、エンジニアとしての心がけ、哲学、シンプルな原則、そのようなものたちだ。

![CB94AB2E-2CA3-47C1-8361-9BA1B6B4EEEC_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/26d6b4ae-932c-e4fa-870b-fbba8774aadd.jpeg)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/b656f3d4-e9a1-aeff-a8f3-00fdbdda3df4.png)

ところで本屋で専門書を開けば、数秒で「これだ駄目だ、読む価値がない」と分かる。
今の自分の問題にはフィットしない、難しすぎる、文体が駄目、情報が浅すぎるなどの理由により。

読み解くのが難しい専門書こそ、本屋に立ち寄って選ぶべきだ。
どうぞ未来永劫、専門書に立ち読み禁止のビニールテープが貼られませんように。



<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Cloudの用語整理

クラウドに関わる用語を整理する
# CASB (Cloud Access Security Broker) 
ガートナーが提唱するクラウドサービスに対する情報セキュリティのコンセプト
CASBが提供する機能は、以下の４つ大別される
・クラウドサービスの利用状況の可視化と分析
・セキュリティポリシーの準拠監査やクラウドサービス利用の制御
・データセキュリティ（データ持ち出しのチェック/ブロック）
・脅威の検出と防御

# VPC (Virtual Private Cloud)
クラウド上に作成できるプライべート仮想ネットワーク空間（セグメント）のこと
VPCではルータやDNSなどのネットワーク機能をクラウドサービスで提供する

# SWG (Secure Web Gateway)
URLやアプリケーション別のフィルタ、アンチウィルス、サンドボックスなどのセキュリティ機能をクラウド型で提供するサービス。（オンプレミス型もある）
※サンドボックス・・・隔離された領域でプログラムを実行し、問題発生時においてもほかのプログラムに影響を及ぼさないようにする仕組み
Django Modelの作成からmigration

## モデルを作成
```diff
from django.db import models
+ from django.utils import timezone


+ class Memo(models.Model):
+    title = models.CharField('タイトル', max_length=200)
+    text = models.TextField('本文')
+    date = models.DateTimeField('日付', default=timezone.now)

```

## ターミナル

```
python manage.py makemigrations アプリ名
```

```
python manage.py migrate
```
Mac で brew install python したけど "command not found: python" "command not found: pip" ってエラーが出やがってよ

# エラー

```
$ python
zsh: command not found: python
```

# 実行ディレクトリを見てみる

```
$ ls /usr/local/bin/ | grep python
python-build@
python3@
python3-config@
python3.7@
python3.9@
python3.9-config@
```

python3 コマンドがあるので、そちらを使う


```
$ python3
Python 3.9.12 (main, May  8 2022, 18:05:47)
[Clang 13.1.6 (clang-1316.0.21.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
```

起動できた

# pip

pip も pip3 という名前になっていやがった


```
$ ls /usr/local/bin/ | grep pip
pip3@
pip3.9@
```

# バージョン名なしで利用する方法は？

シンボリックリンク貼れば良いだけなんだけど、良い方法は何なのか
誰か教えて



<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
74 解答

この問題はbinary searchの使用を目的としている。
# 参考
[Nick White](https://www.youtube.com/watch?v=eT0UqrYuqbg)
# n^2

```Java

public boolean searchMatrix(int[][] matrix, int target) {
		int m = matrix.length;
		int n = matrix[0].length;
		
		
		for(int i = 0; i < m; i++) {
			for(int j = 0; j < n; j++) {
				if(matrix[i][j] == target) {
					return true;
				} 
			}
			
		}
		return false;
	}
```
# logn

```Java
public boolean searchMatrix(int[][] matrix, int target) {

		int rows = matrix.length;
		int columns = matrix[0].length;

		int left = 0;
		int right = (rows * columns) - 1;

		if (rows == 0)
			return false;

		while (left <= right) {
			int midpoint = left + ((right - left) / 2);
			int midpoint_element = matrix[midpoint / columns][midpoint%columns];
			if (midpoint_element == target) {
				return true;
			} else if (midpoint_element > target) {
				right = midpoint - 1;
			} else if (midpoint_element < target) {
				left = midpoint + 1;
			}
		}
		return false;
	}
```
PostgreSQL client 10をDebianにインストール

https://www.postgresql.org/download/linux/ubuntu/

```bash
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'

wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

sudo apt-get update

sudo apt-get -y install postgresql-client-10
```