OmniAICreator/Qiita-1.07M huggingface dataset:
コネクションプールの適正サイズの求め方

Spring Bootアプリケーションのパフォーマンスチューニングをする機会があったのですが、その際に読んだ[HikariCP](https://github.com/brettwooldridge/HikariCP)（Java製のコネクションプールライブラリ）のドキュメントに興味深い記述があったので紹介します。

オリジナルのドキュメント: About Pool Sizing
https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing

## DBコネクションは（ほとんどの場合）多すぎる

英語が苦手でなければ、まず以下の動画を見てください。ここでは、DBコネクションの数を2000 => 96に減らすことで、レスポンスタイムが100ms => 2msに改善するデモが行われています。

https://www.youtube.com/watch?v=xNDnVOCdvQ0

このデモ内では、Webアプリケーションを想定して、約10000のユーザが同時にアクセスするようなシナリオを想定しています。このような場合でも、WebアプリケーションからDBサーバへの接続は100足らずで問題なく、コネクション数を減らした方が高速に処理できます。

なぜこのようなことが起こるのでしょう？

## CPUのタイムスライシング

複数の仕事を同時に行う必要がある場合、CPUはそれらを少しずつ時間を区切って実行します。これをタイムスライシングといいます（[基本情報技術者試験](https://www.fe-siken.com/kakomon/16_haru/q31.html)にも出題されてますね）。

タイムスライシングによってCPUは複数の仕事を同時に行えますが、それが仕事を最速で終わらせる方法とは限りません。2つの仕事があるとき、それを順番にやる場合と同時にやる場合では、同時にやる場合の方がスイッチングコストの分遅くなります。

DB接続数が多い場合、DBサーバのCPUは多くのタスクを同時に行う必要があり、レイテンシが大きくなります。

## パフォーマンス観点からコネクション数を考える

では、DBサーバのパフォーマンスを最適化できるコネクション数はどの程度なのでしょうか？　HikariCPのドキュメントでは、[PostgreSQLのドキュメント](https://wiki.postgresql.org/wiki/Number_Of_Database_Connections)を参照し、

```
connections = ((core_count * 2) + effective_spindle_count)
コネクション数 = (コア数 * 2) + スピンドル数
```

と記載しています。

スピンドルというのはHDDの軸のことです。DBサーバがSSDを搭載している場合、スピンドル数は0とみなすことができます。なぜなら、スピンドル数の分コネクション数を増やしているのは、HDDではI/Oの待ち時間を考慮する必要があるからです。この点、SSDはHDDよりI/Oが速いので、HDDのようにI/Oの待ち時間を考慮してコネクション数を増やす必要はありません。

現在では多くのDBサーバがSSDを使っているので、「コネクション数 = コア数 * 2」がDBサーバのパフォーマンスを最大限に発揮できるコネクション数であると考えられます。

## デッドロック回避のためのコネクション数

1つのactor（プロセス、スレッドなど、アプリケーションの実行単位）が多くのDBコネクションを使うと、コネクションが解放されず、他のactorがコネクションを取得できなくなります。これを「Pool-locking」と呼んでいます。

これは主にアプリケーションの側で解決すべき問題であると考えられます。しかし、アプリケーションの改修が難しくコネクションプールの設定で調整する必要がある場合、以下の式によって、最低限必要なコネクション数を求めることができます。

```
コネクション数 = アクターの最大数 * (同時に保持する必要があるコネクション数 - 1) + 1
```

例えば、最大で8つのスレッドが最大で3つのコネクションを保持する必要がある場合、最低限必要なDBコネクションの数は 8 * (3-1) + 1 = 17となります。

Webアプリケーションのように、DBコネクションをすぐに解放するような場合には、パフォーマンス重視のコネクション数にすることが望ましいです。一方で、実行時間の長いバッチなど、DBコネクションを保持し続ける必要のあるアプリケーションでは、デッドロックによって処理が止まることがないようにする必要があります。

このように、コネクションプールのサイズはアプリケーションの特性を考慮に入れて決める必要があります。

## 複数のサーバからDB接続する場合

ここまで読んで、アプリケーションサーバが複数ある場合はどうするの？　と思った方もいるでしょう。

HikariCPのドキュメントには記載がありませんが、HikariCPのissueで複数のアプリケーションが1つのDBサーバを共有している場合について議論されています。
https://github.com/brettwooldridge/HikariCP/issues/1023

このissueによると、アプリケーションサーバの台数増にしたがって、1アプリケーションサーバあたりのコネクションプールサイズは減らすのが基本的な考え方になります。

つまり、

```
1アプリケーションサーバあたりのコネクション数 = DBサーバのコア数 * 2 / アプリケーションサーバの台数 
```

ということです。

しかし、実際に全てのアプリケーションサーバがコネクションを限界まで使い切るとは限りません。これについてはプロファイラを使って、各アプリケーションが実際に同時に利用するコネクション数の最大数を求め、それをコネクションプールの上限に設定することが望ましいです。

HikariCPでは [Dropwizard Metrics](https://github.com/brettwooldridge/HikariCP/wiki/Dropwizard-Metrics) を使ってコネクションプールのメトリクスを取得できます（Dropwizardというフレームワークの名前が付いてますが、[Spring Bootでも利用できます](https://stackoverflow.com/questions/28615203/how-do-i-configure-hikaricp-and-dropwizard-coda-hale-metrics-in-spring-boot-appl)）。
【備忘録】Swift 実践入門について　第2章

Swift 実践入門のまとめ。
分からない部分の抜粋も記載し、解決できたら随時更新していきます。
なお、ここに記載している以外でも「わけわからん…」となっている部分も多々ありますが、
今は必要ない、と言い聞かせて飛ばしています。


第2章
変数・定数
理解度：80％くらいか
2.1～2.3まではまだOK。

2.4 式の組み立て…変数・定数に何を入れることができるのか
メンバー式…変数aに値を代入し、a.countなどで表すこと。変数のcountなどのことをプロパティ。
クロージャ式…1つの処理のカタマリ。関数と異なり関数名などが不要。本書では以下の例で示されていた。
let original = [1, 2, 3]
let doubled = original.map({value in value * 2})
doubled //[2, 4, 6]
この例では定数に処理のカタマリも持ってこれますよ、という紹介か。
UTF-8とサロゲートペアって関係あるの？

# TL;DR
関係ないです。

# はじめに
サロゲートペアってよく分からんけど、UTF-8使うときに気にしないといけないものなの？
を調べたときによく分からなかったので、同じようにハマった人の手助けになれば。

# Unicodeって？
世界中の文字を全部詰め込んだ文字セット（文字コードの集合）を作ろうぜ！
というコンセプトで作られたものです。
今もなおどんどんアップデートされ、文字が追加されています。
（最近は絵文字とかが追加されている）
たとえば「あ」だったら、`U+3042`に割り当てられます。
その他の例は以下です。

|文字|Unicode|
|:-:|:-:|
|A|U+41|
|Ω|U+3A9|
|語|U+8A9E|
|😊|U+1F60A|

# UTF-8とかUTF-16とかUTF-32って？
エンコード方式。
文字をどうやってデータに変換するかのルール。
UTF-8：文字を8ビット**単位**に変換する。
UTF-16：文字を16ビットに変換する。
UTF-32：文字を32ビットに変換する。
実際に変換した例が以下です。

|文字|Unicode|UTF-8|UTF-16|UTF-32|
|:-:|:-:|:-:|:-:|:-:|
|A|U+41|41|0041|00000041|
|Ω|U+3A9|CE　A9|03A9|000003A9|
|語|U+8A9E|E8　AA　9E|8A9E|00008A9E|
|😊|U+1F60A|F0　9F　98　8A|**D83D　DE0A**|0001F60A|

あれ？なんか1人ルール違反してる人がいますね。
ただ、大人の世界では、ルール違反が起きたら、ルールのほうを変えてしまうことがあります。
この例外ルールが**サロゲートペア**です。

# サロゲートペアって？
Unicodeはどんどん文字を追加しているうちに、16ビットでは表現しきれない情報量になってしまいました。
でも、`UTF-16：文字を16ビットに変換する。`というのはもう決めてしまっていた後なので、なんとかしないといけません。
そこで、**2文字で1文字を表現しよう！**となりました。
人間、追い詰められるとワケ分からんこと言い出しますね。
2文字だから「ペア」です。
＃サロゲートの意味は「代理」だそうです。

# まとめ
UTF-8は8ビット**単位**でエンコードを行うため、16ビットを超える文字でも問題なく変換することができます。
つまり、**UTF-8にサロゲートペアはありません。**
＃同様に、UTF-32にもサロゲートペアはありません。
Oracle Code One 2020について

この記事は[SRA Advent Calendar 2020](https://qiita.com/advent-calendar/2020/sra)の1日目の記事です。

こんにちは！　関西事業部の佐々木です。

#今年のOracle Code One
1996年から20年以上続いてきたJavaOneは2018年からOracle Code Oneになりました。
去年のOracle Code One 2019まではずっとサンフランシスコで行われていたのですが、今年のOracle Code One 2020はラスベガスで開催する予定でした。
しかし今年は新型コロナウイルスの影響によりオンライン実施となりました。

##セッションを視聴したい方へ
Oracle Code One 2020のオンラインセッションは[ここ](https://developer.oracle.com/developer-live/java/)から見ることができます。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100799/8a50d4ff-5d8b-9986-c3d2-e2af050b2657.png)
Oracle Code Oneに興味はあるけど参加する機会がなかった方はぜひご視聴ください。

##オンラインで良かったこと
Oracle Code Oneがオンラインで実施されたことによって良かったことがいくつかあります。

###参加費がタダ
まずは何と言っても参加費が無料だということです。
Oracle Code Oneは参加料が10万円以上するのですが、今年は参加料はかかりませんでした。

###経費がタダ
去年まではアメリカで開催されていたので日本から参加するには旅費・宿泊費などがかかります。しかもサンフランシスコのホテル代はかなり高額です。
旅費・宿泊費だけでも毎年だいたい20万ほどはかかってたのでかなり節約できます。
（私の場合費用はすべて会社持ちでしたが）

###自宅でゆっくり視聴できる
会場まで足を運んでセッション開始前に列に並んだり、（人気のセッションの場合）空いてる席をさがしたりする必要が無く、家のPCでゆっくり視ることができます。

###字幕付きでセッションを聴ける
オンラインはYouTubeで配信されたので、YouTubeの機能を使って字幕を表示したりできます。自動翻訳で日本語字幕にもできますが、私は英語の勉強も兼ねて英語字幕で視聴してました。

##オンラインで残念だったこと
逆にオンラインで開催されたために残念だったこともあります。

###セッションの数が少ない
これはオンラインそのものが原因ではないんですが、例年4～5日間で数百のセッションがあったのが今年は1日間だけで10程度セッションがあっただけでした。

###現地の雰囲気や観光を味わえない
セッション会場でのスピーカーを生で観たり、オーディエンスのリアルタイムの反応なんかはオフライン開催ならではだと思います。
また、「蟹One」という日本からのメンバーが集まって蟹を食べたりするのが恒例なのですが、普段関西にいる身としては東京のJava技術者と直接会える貴重な機会でもあり、そういった場がないのはとても残念です。
さらに普段海外旅行を全くしない私にとって、Oracle Code Oneは海外の雰囲気を味わえる機会でもあります。
毎年Chipotleというメキシコ料理のファストフードの店に行くのですが、今年は食べることができず何を血迷ったのかChipotleのロゴのスマホケースを作ってしまいました。

![IMG_4034.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100799/74782877-2538-51e8-9e8e-ecdac64690cd.jpeg)

##来年はどうなる？
アメリカは今も新型コロナウイルスが猛威をふるっています。
正直来年の現地開催も厳しいのではないでしょうか。


世界中の多くの人も同じかもしれませんが、早く新型コロナウイルスの脅威が落ち着いて平和な日が訪れることを願いたいと思います。
I wish you a Merry Christmas.
KeyStoreのjksファイルを復元する方法


拡張子jksは、KeyStoreファイルです。(ここではAndroidアプリ開発で利用)

CIの環境変数に入れようと思ったところ、中身がバイナリでした。

## 方法

以下でテキストにデコードできます。

```sh
openssl base64 -A -in .signing/release.jks
```

自分の場合は2764文字のテキストが出力されました。

CI上では、↑で出力されたbase64テキストを環境変数に設定して、
以下のようにまたjksにエンコードして使うのが一般的のようです。

```sh
echo $KEYSTORE_BASE64 | base64 -d > .signing/release.jks
```

## note

タイトルはよく知らない人（自分）がこんなキーワードで検索する。というのを考えて設定しました。

中身自体はいろんな記事にありますがQiitaはピンポイントで索引できるといいなと思いました。
【作業高速化】Macターミナルで使えるショートカット【10選】

#はじめに
Macのターミナルで、deleteキーを押しっぱなしにして、一文字ずつ消した経験はありませんか？
実はショートカットキーを使うことで、一気に文字を削除することが可能です！
他にも、ショートカットキーで出来ることは、たくさんあります。

ショートカットキーを活用することで、あなたの作業を高速化していきましょう！

#環境
・MacOS Catalina 10.15.7
・zsh

#ショートカットキー

###カーソル移動

| キー |  意味  |
| ---- | ---- |
|control + A | カーソルを行頭まで移動 |
|  control + E  |  カーソルを行末まで移動  |
|  option + →  |  カーソルを1単語右へ移動  |
|  option + ←  |  カーソルを1単語左へ移動  |


###カット＆ペースト

| キー |  意味  |
| ---- | ---- |
|control + U|カーソル位置から行頭までカット|
|control + K|カーソル位置から行末までカット|
|control + W|カーソル位置の1単語をカット|
|control + Y|カットした内容をペースト|


###履歴検索

| キー |  意味  |
| ---- | ---- |
|control + R|過去に使用したコマンドを検索|

###その他

| キー |  意味  |
| ---- | ---- |
|control + L|画面をクリア|

#参考
Macターミナルの覚えておきたい基本情報・ショートカット・コマンドまとめ
https://do-zan.com/mac-terminal-command-shortcut/

#最後に
いかがでしたか？
カット＆ペーストがMac標準の『control + X』や『control + V』でないなど、少し戸惑ってしまうところもあるかもしれません。
しかし、ショートカットキーを使いこなせば、よりターミナルを高速で使いこなすことができます。
ぜひ、コマンドを一つ覚えるところから始めてみましょう！
AWS SAM CLIをLinux、macOSにインストールする

# AWS SAM CLI

## 準備

※参考：[Installing the AWS SAM CLI on macOS](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install-mac.html)
※参考：[AWS CLIをmacOSにインストールする](https://qiita.com/homelan/items/297d52ac2b1d65c1e769)

1. AWSアカウントを用意する。
1. Administrator権限を持つIAMユーザーを用意する。
1. IAMユーザーのアクセスキー、シークレットアクセスキーを払い出す。
1. credentialsファイル、configファイルを作成する。
1. Dockerをインストールする。
1. Homebrewをインストールする。
1. SAM CLIをインストールする。

## 共通

1. Linux、WSL2、macOSで次のコマンドを実行し、`brew`をインストールする。

    ```shell
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
    ```

## Linux、WSL2にインストール

1. Ubuntu on WSL2`では、4行目のechoコマンドを実行すれば良い。

    ```shell
    test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv)
    test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
    test -r ~/.bash_profile && echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.bash_profile
    echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile
    ```

## 共通

1. `brew`コマンドがインストールされていることを確認する。

    ```shell
    brew --version
    ```

1. 次のコマンドを実行する。

    ```shell
    % brew tap aws/tap
    % brew install aws-sam-cli
    ```
1. インストールされたことを確認する。

    ```shell
    % sam --version
    ```

    ```text
    SAM CLI, version 0.47.0
    ```
プリセールスエンジニアとして経験を積んだ話

iOS Androidなどのモバイル受託開発を4年ほど経験し
その中でもプログラマというよりはPMもどきや本タイトルでもある
プリセールスエンジニアとしての経験も積めたので共有させてください。

# プリセールスエンジニアとは？
営業と協力し開発的目線から受注までの段取りを手助けする役割をもつエンジニアです。

まず受託開発を行うにあたりスタートアップ企業などだと仕事を引っ張ってくる必要があります。

主にプログラマの方はポジションが違うので感じることが
少ないかもしれませんが、仕事は自然と湧いてくるわけではありません。
営業が汗水垂らして一生懸命交渉した後に発注がもらえるわけです。

ただ営業が数字にのみ目が行き
「どんな案件でも取れたらいいやろ！」という考えになってしまっては
要件が全く決まっていない状態やそもそも開発にとって不利な状況下から
案件がスタートすることも少なくありません。
こうなると開発メンバーが疲弊し、生産性は落ち、いいものができず
案件が炎上しお客さんも激おこになってしまうわけです。

こうならないためにも受託の話があれば最初からプリセールスエンジニアとして
営業と同行しお互い違う立場でヒアリングをしてより良い選択をしていく必要があります。

# プリセールスエンジニアに必要なスキルは？
#### 1, 幅広い技術的知見
今社会でどのような言語やフレームワークが主に使われていて
どういう構成が多いのかは理解しておく必要があります。
特にシステム連携の話になるとhttp, TCP/IP, WebAPI, JSON, FTP、Hulftなど
プロトコルや用語は押さえておかないと話ができません。
例）最近はオンプレ構成よりクラウド構成が人気ですよ。など

#### 2, 相手に伝えることを目的とした説明
上記で書いたような用語などはお客さんが必ず知っているわけではありません。
相手の知識を伺いながら専門用語は使わず噛み砕いて相手に伝える表現をするのも
プリセールスエンジニアとしては特に必要なスキルです。

#### 3, 問題解決を目的とした豊かな想像力
お客さんが悩んでいることをどのようなソリューションで解決できるかを
提案するスキルも必要です。システムを導入するにあたり
政治的背景、費用感、スケジュール感、コンプライアンス、現場の声など
様々な要因をヒアリングした上で具体案を想像し、この方法ならできるという
落とし所を見つけ、お客さんと共に形作る流れを作るためにも
最初の具体例や叩き台といった部分があるかないかで案件の進み具合が変わってきます。
話を前に進めるためにも様々な要因を考慮した想像力が必要です。

# プリセールスエンジニアのつらみ
#### 必要な知識が多すぎる
業種にもよるとは思いますが、私がおかれている環境下においては
物流、医療、製造、アパレルなど多岐に渡ります。
それぞれの業務知識も必要となってきますし、こればかりは訪問件数を
重ねて経験値を積むしかないので最初の頃はわからないことだらけだと思います。

#### 営業的観点と開発的観点の両方を常に持ち合わせる必要がある
技術的な観点はもちろん抑える必要がありますが営業の手助けができるよう
受注までの道のりを把握しておく必要があります。
お客さんも費用を出して発注するわけですから担当者が
上司に稟議をあげたりプレゼンをしたりします。
自分がどれだけ担当者へいいプレゼンができたとしても決裁者に響かなければ発注はもらえません。
この辺りのフォローもしつつ決裁のリードタイムをヒアリングし
社内のリソースを調整しておくのも仕事のうちです。
（与信枠、NDA、口座の取引、契約書の確認などはまだできておらず修行の身です…）

# 最後に
営業はどうしてもお客さんから「営業」という肩書もあり信用されにくい背景もあります。
そこに開発メンバーとしての一言があるだけで信頼もしてもらえたりします。
もしこの記事を読んでくれている中で
- 激しい要件変更で疲弊している
- 要件が決まっておらず思うように進まない
- 営業が適当な話を受注してくる
- 営業が受注に苦戦している

など悩んでいる点があれば自分がプリセールスエンジニアとして
営業と同行し一歩目を踏み出すのはいかがでしょうか。
JavaScriptの関数はオブジェクトに過ぎないのでプロパティを持たせることができる

## 百聞は一見に如かず

```js
function hello() {
  return console.log(`${ hello.message } ${ hello.user }.`)
}
hello.message = 'hello'
hello.user = 'momo'
hello() // -> hello momo.
console.log(hello) // -> { [Function: hello] message: 'hello', user: 'momo' }
```

面白いですね。
なお`hello.name`には関数名(hello)が格納されている。

初めは`hello.user`ではなく、`hello.name`で記述したけれど関数名が表示されて、なるほどっと思った。
【Rails】mark_for_destruction を 使って特定の条件のレコードを削除する。

# 使用ケース
「特定のカラムが空である場合にはそのレコードを削除したい」みたいなときに便利です。
そのレコードに削除マークをつけておくと削除されるイメージで実装できます。

# サンプルコード

前提として users は name カラムを持つとします。

name の値が nil か 空文字であればそのレコードを削除したいみたいな時は、以下のように実装できると思います。

今回はインスタンスメソッドを定義し、before_validationのコールバックで実行しました。

~~~app/models/user.rb 

before_validation :delete_user_if_name_blank

def delete_user_if_name_blank
  self.mark_for_destruction if name.blank?
end
~~~

if 文を使えば色んな条件で適用できますし、アソシエーションしているレコードも削除できたりするので色々と応用が効きそうですね。
【Bash】大量のファイルから100個取り出して別のディレクターに移す方法。


`dir_A`内にある大量のファイル(拡張子は`.txt`)から100個取り出して、`dir_B`に移す方法。

``` bash
count=0
while read file
do
  if [ $count -ge 100 ]; then
    break
  fi
  count=$(( $count + 1 ))
  mv "${file}" "./dir_B/"
done < <(find ./dir_A -name '*.txt')
```

# 参考

https://qiita.com/daei/items/76635f9fbf25824b525e
リモートのCentOS8でdockerコンテナをpodmanにて動作、ローカルのVSCode_arm64とソースコード同期させて開発 

環境構築

事務所のCentOS_x86_64にpodman(docker互換機能)を使ってdockerコンテナを起動し、VSCodeのsftp拡張でソースコードをリモート同期できるようにした。朝からやって完成。コツはCentOS8の標準pythonが3.6 なので3.8にアプデすること（これに気がつくまでに時間かかった）、そうでないと podman-compose が動作しない。

podmanはdockerほぼ完全互換だけど問題はdocker-composeに相当するものが存在しないこと。どうもRedhatは kubernetesこそが正統なオーケストレーションだとして認めていないらしい。仕方ないから不完全互換だけどサードパーティのpodman-compose を使ってなんとかしのぐ。動かすにはちょっとコツがある。具体的にはトップレベルのディレクトリ名は小文字のみ使用可能。

ちょっと嬉しいのはpodmanはRedhat純正だけあって、cockpitというwebベースの管理ツールを使ってコンテナ監視ができること。コンテナのコンソールをちょっと覗いたりできて、docker-desktopの代替としてはなかなかいい。

しかしこれで完全にApple Siliconだけで仕事できるようになった。事務所のInterl機は古いとはいえメモリとSSDリソース有り余ってるのでローカルのVM動かすよりも全然速いし、ローカルのメモリ16Gでも余裕だ。
JavaScriptで加速度センサーひろってみた

# 加速度センサーを拾ってみた

`window.addEventListener("devicemotion", ハンドラとなる関数);`
で拾えます。（使えるかどうかは、使用しているデバイスとブラウザに依存します。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438183/a02386d0-ca2a-bfec-4cec-cc4b4a02fc6b.png)

- 赤 ・・・ `event.accelerationIncludingGravity.x` の値
- 緑 ・・・ `event.accelerationIncludingGravity.y` の値
- 青 ・・・ `event.accelerationIncludingGravity.z` の値
- 白 ・・・ 上記をベクトルとみなしたときの長さ。（それぞれを2乗して和を取って平方根を取ったもの）

# CodePen

（※センサを搭載していないデバイスで閲覧している場合、何も面白くないものが表示されていると思います。）

センサを搭載してても、Qiita記事への埋め込みだとセンサが取れないっぽい。
CodePenのサイトから直接閲覧する必要あり。

スマホで[CodePenのサイトを直接開いて](https://codepen.io/kob58im/pen/wvzvWwa)、スマホを上下方向などに動かすと波形が振れると思います。（壊さないようにお気をつけください。）

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="result" data-user="kob58im" data-slug-hash="wvzvWwa" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="g-Sensor">
  <span>See the Pen <a href="https://codepen.io/kob58im/pen/wvzvWwa">
  g-Sensor</a> by kob58im (<a href="https://codepen.io/kob58im">@kob58im</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 参考
 - [デバイスの方向の検出 - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Detecting_device_orientation)
 - [JavaScriptで加速度センサーとジャイロスコープから値を取ってみた | 情報科　いっぽ　まえへ！](https://joho-ka.mints.ne.jp/accelerometer-and-gyroscope?doing_wp_cron=1606389679.2029790878295898437500)
CentOS8.2でMySQL8.0の定期的なバックアップを行う手順

| [../](https://qiita.com/taconana/items/e45f19e83c825a9ba75e) |
---
VPSサーバー（CentOS8.2）にMySQL8.0をインストールした。定期的にMySQLデータベースのバックアップを作成するようにしたい。その手順をメモしておく。バックアップは、毎日4:00に実行し、過去14日分を残すようにする。スケジュールはcron.dに登録して行う。

## 定期バックアップのシェル作成

以下のようにシェルファイルを作成する。例では、/var/share9/mysql-backup/mysql-backup.shとしている。データベースの接続情報は適宜、変更のこと。

```bash

$ vi /var/share9/mysql-backup/mysql-backup.sh 
#!/bin/sh

keepday=14		# 何日間をサイクルで回すか。
host=xxx		# ホスト名
dbname=kankeri	# データベース名
user=root		# ユーザー名
pwd=***			# パスワード

dst=/var/share9/mysql-backup/backup-${host}
bak=${dbname}.bak
d1=`date +%Y%m%d`
d2=`date "-d${keepday} days ago" +%Y%m%d`
new=${dbname}-${d1}.tar.gz
old=${dbname}-${d2}.tar.gz

cd ${dst}
/usr/bin/mysqldump -u${user} --password='${pwd}' --opt ${dbname} > ${bak}
tar zcvf ${new} ${bak} > /dev/null 2>&1
if [ $? != 0 -o ! -e ${new} ]; then
echo backup failed ${new}
exit 1
fi
if [ -e ${old} ]; then
rm -f ${old}
fi

echo ----------- ${dst}
ls -lag  ${dst}
```

## cron.dへスケジュール登録

毎日4:00に実行されるようにcron.dに登録する。スケジューラはcrondというサービスであるが、登録方法は、cron.dやcrontabやcron.dailyなどがある。設定方法は同じである。私は、cron.dに登録することにした。/etc/cron.d/mysql-backup を以下のように作成した。毎日4:00に前述のmysql-backup.shを実行させる。

```bash

vi /etc/cron.d/mysql-backup
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
  0 4 * * * root      /var/share9/mysql-backup/mysql-backup.sh

```

## 動作確認

まず、mysql-backup.sh がrootで正常に動作することを確認しておく。mysql-backup.shの所有者はrootで、権限は700であること。パスワード埋め込みのシェルなので、他者が触れないようにしておくこと。

そしてcrondサービスを再起動させておく。1日待てば確認できる。気が短い方は、cron.hourlyに変更して確認してみてもいい。

```bash
# rootで動作するかどうかの確認
$ su -
$ ls -lag /var/share9/mysql-backup/mysql-backup.sh
-rwx------ 1 root  680 11月 28 10:32 mysql-backup.sh
$ /var/share9/mysql-backup/mysql-backup.sh

# cron.dに登録されているか確認
$ ls -lag /etc/cron.d/
-rw-r--r--   1 root    52 11月 28 10:12 mysql-backup

# crondを再起動して、追加したcron.dを読み込ませる。
$ systemctl restart crond
$ systemctl status crond
```
以上

| [../](https://qiita.com/taconana/items/e45f19e83c825a9ba75e) |
---
[個人開発あるある] 失われたリポジトリを発掘する旅に出る

PCの中に埋もれたgitリポジトリありませんか？私はたくさんあります。以下の方法で探り当てたリポジトリを見ると自分では全然覚えてない作りかけの物が出てきました。実家のタンスの奥から子供の頃のオモチャが出てきたような気分です。

もともとは「数ヶ月さわってないプロジェクトを久しぶりに開くにはどこに置いてたか探すことから始めなきゃならない」という当たり前のことに気付いたからでした。
[ghq](https://github.com/x-motemen/ghq)等を使ってる方はちゃんと管理できてるんでしょう。しかしリポジトリ迷子の私みたいな方はたくさんいると思います。そして思いついたのが[peco](https://github.com/peco/peco)を使った方法です。

![peco](https://camo.githubusercontent.com/e56253a16c88046f6bbdd4c8031d349604db7d67d05e2ea51b0d66a1f99038cb/687474703a2f2f7065636f2e6769746875622e696f2f696d616765732f7065636f2d64656d6f2d70732e676966)
*peco公式より*

こんな感じでリポジトリの一覧から選んでVSCODEで開けたら便利ですよね。
その方法を実現する手順は以下の通り。

1. findコマンドでPC内からリポジトリの一覧を作成＆保存
2. zshrcにpecoの設定を追加
3. zshrcにfindのエイリアスを追加

これだけです。

ちなみにpecoのインストールについては公式を御覧ください。Homebrew, Scarf, apt等でもインストールできます。

[peco/peco: Simplistic interactive filtering tool](https://github.com/peco/peco#installation)

## 1. findコマンドでPC内からリポジトリの一覧を作成＆保存

```bash
> find ~/Documents -regex ".*/.git" > /path/to/git_paths.txt
```

引数の`~/Documents`はgitリポジトリが眠っていそうな大体の場所です。まさか`~/Movies`とか`~/Music`なんかにリポジトリを置いてる人はいないでしょう。findは時間がかかるのである程度検索範囲を絞ったほうが良いです。私は基本的に`~/Documents`以下に置いているのでここを検索対象にしました。

`/path/to/git_paths.txt`は一覧を保存する場所です。適当なpathを指定してください。
ちなみに私の場合、コマンドの実行は約3分。170のリポジトリが発掘されました。

## 2. zshrcにpecoの設定を追加

.zshrc(他のshellならその設定ファイル)を開いて以下を追記します。

```bash
function peco-select-repository() {
  local repo=$(cat /path/to/git_paths.txt | sed s/\.git$// | peco)
  if [ -n "$repo" ]; then
    print -z "${repo}"
  fi
}
alias gp=peco-select-repository
```

内容を解説すると２行目のcatでファイルを読み込み、sedで末尾の`.git`を削除(取得したいのは.gitディレクトリの親ディレクトリなので)、そしてpecoに渡しています。

4行目の`print -z "${repo}"`でパスを出力します。そのまま実行しても仕方がないので目的により書き換えたほうが良いかもしれません。

```bash
print -z "cd ${repo}"   # 移動したい場合
print -z "code ${repo}" # VSCODEで開きたい場合
```

個々の目的に応じて書き換えてください。

これを保存してターミナルを開き直すと使えるようになります。
`gp`+returnでリポジトリの一覧が表示されます。

## 3. zshrcにfindのエイリアスを追加

1で実行したfindは定期的に行って更新する必要があります。とは言っても最近のリポジトリは覚えているでしょうから頻繁に行う必要はありません。数ヶ月に１回で十分だと思います。
その時に`find hogehoge~~~`と書くのは面倒なのでaliasを設定しておきます。.zshrcに書きます。

```bash
alias reposearch='find ~/Documents -regex ".*/.git" > /path/to/git_paths.txt'
```

ターミナルを開き直すと`reposearch`でfindを実行できるようになります。

## まとめ

最終的に私の`.zshrc`に追記したのはこんな感じです。
`my_git_repo.txt`はzshrcの近くにある方が管理しやすいと思うので同じ階層の`~/.zsh/`に置くことにしました。

```bash
function peco-select-repository() {
  local repo=$(cat ~/.zsh/my_git_repo.txt | sed s/\.git$// | peco)
  if [ -n "$repo" ]; then
    print -z "code ${repo}"
  fi
}
alias gp=peco-select-repository
alias reposearch='find ~/Documents -regex ".*/.git" > ~/.zsh/my_git_repo.txt'
```
IPS/IDSってなに？

## 勉強前イメージ

なにか防ぐやつ？
でもfirewallっぽいイメージ持ってない。。
ちゃんと勉強しよう

## 調査

### IPS/IDS とは

- IPS ... Intrusion Prevention Systemの略
	- 不正侵入防止システム と呼ばれています
	- 不正なアクセスの侵入を遮断します。
- IDS ... Intrusion Detection Systemの略
	- 不正侵入検知システム と呼ばれています
	- こちらは不正なアクセスがあれば、管理者へ通知を行います。

IPSとIDS2つ合わせることによって、不正侵入防止・検知システムと呼ばれています。

### IDSの通信のチェックの種類

何が正常か、異常をチェックする方法の違い

- アノマリ型
	- `正常`な通信を定義しておく
	- 定義された以外の通信は不正と判断
	- ホワイトリストに近い手法
- シグネチャ型
	- `異常` な通信を定義しておく
	- 定義された通信が来たら不正と判断
	- ブラックリストに近い手法

![あのまりシグネチャUntitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/a356e01f-93e2-3e0e-e9a7-4536b254a676.png)


### IPS/IDSのパケット監視対象の種類

- ネットワーク型(NISD)
	- ネットワークを流れる通信を監視
	- 直接接続しているネットワークでのみ検知が可能
- ホスト型(HIDS)
	- 監視対象のサーバにインストールして使われる
	- 対象のサーバに入ってきた通信を監視

![ネットワーク型ホスト型Untitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/cf9ccc5a-bd7d-6ad9-c4b3-6230a292c26e.png)

### firewallとどう違うの？

firewallはネットワークなどの不正アクセスをブロックします。
しかし不正に侵入されてしまうと、自由になってしまうのでネットワーク内を監視しブロックするのがIPS/IDSの約目です。

![firewallとの違いUntitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/57376569-1ae1-7fca-f0f2-6a62fb9852e3.png)

firewallの場所はネットワークの外側、DMZと内部の仲介をしたりします。
しかしIPS/IDSは
ホスト型はサーバにインストールされていますが、
ネットワーク型はfirewallの外にいたり、内部やDMZのネットワーク内に設置されます。

![IPSISDの場所Untitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/e2746db0-9045-f67a-1cd7-5bdc6a3052c9.png)

## 勉強後イメージ

確かに内部に入ってしまった通信に関しての監視はないなってこれを見て気づいた。
入られてからもなおより一層の対策をすることで安全に運用できる....

## 参考

- [IDS・IPSとは？不正侵入検知・防御サービス解説](https://www.kagoya.jp/howto/network/ids-ips/)
- [IDSとIPSの意味とその違いとは](https://www.shadan-kun.com/blog/measure/2842/)
- [IDS・IPSとWAFの違いとは？ファイアウォールとの相違点も解説](https://it-trend.jp/ids-ips/article/difference)
Raspberry Pi を無線LANコンバータ化

やってみました。

ベースとした情報：[Raspberry Piでルータを構築](https://netlog.jpn.org/r271-635/2013/04/raspberry_pi_router.html)

Raspbian Busterを利用しました。
BusterならNIC間のフレーム転送ができるとかできないとか色々記事がありましたが、
結局私にはできなかったので、NAPT化させる方法を取りました。

LAN向けにdhcpサーバを立てる。
参考：[Raspberry Pi BrusterにDHCPサーバーを設定する](https://zoe6120.com/2019/07/13/1016/)

```
subnet 192.168.0.0 netmask 255.255.255.0 {
 range 192.168.0.100 10.0.121.110;
 option routers 192.168.0.254;
 option domain-name-servers 192.168.0.254, 8.8.8.8;
 ignore declines;
}
```

eth0をUpさせないと、DHCPサービスを起動できなかった

パケット転送
/etc/sysctl.conf

```
net.ipv4.ip_forward=1
```

NAPT化

```
sudo iptables -t nat -F
sudo iptables -t filter -F
sudo iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o wlan0 -j MASQUERADE
sudo iptables-save > /etc/iptables
```
Power Queryで列追加・置換方法をまとめていく

便利な列追加方法について追記していきます。


| 関数 | 説明 |
| --- | --- |
| Table.FromRows(list, columnName)| 二次元リストからテーブル作成 |
| Table.AddColumn(table, newColumnName as text, columnGenerator as function)| 列の追加 |
| Table.Join(table1, key1, table2, key2, optional joinKind as nullable number, optional joinAlgorithm as nullable number, optional keyEqualityComparers as nullable list) | テーブルの横結合 |

# テーブルの結合

```:テーブル1の作成
= Table.FromRows(
    {{"Bob", 25},
    {"Tom", 32}},
    {"name", "age"})
```



![2020-11-28_10h04_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/909daec3-2af3-81d6-4d47-875ab2aad5c9.png)


```:テーブル2の作成
= Table.FromRows(
    {{"Bob", "apple"},
    {"Tom", "arange"}},
    {"name", "favorite"})
```

![2020-11-28_10h04_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/8b1afe3d-94f2-6241-a6dd-eb55f89264a0.png)

```:テーブルの結合
= Table.Join(ソース, "name", カスタム1, "name")
```

ソースとカスタム1が先に作ったテーブル名でそれぞれのキーを偶数の引数で指定。

![2020-11-28_10h04_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/ca81f2fb-0ede-21c2-91ea-c8101b134759.png)

joinのさせ方はいろいろあるので下記を参考に指定可能
https://docs.microsoft.com/ja-jp/powerquery-m/table-join


以降このテーブル(カスタム2)に列を追加する方法を紹介

# 列の追加

## 四則演算

```:数値の四則演算
= Table.AddColumn(カスタム2, "year", each [age] + 1967)
```

![2020-11-28_10h06_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/a957d602-07e6-5617-926d-fc262068a4ff.png)


## 置換

```:数値の四則演算
= Table.AddColumn(カスタム2, "year", each Text.Replace([name], "Bob", "bob"))
```

![2020-11-28_10h50_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/096ed0af-f8a3-bd54-2bb3-f36c5a037cfe.png)

## 条件式

```:if文の条件式
= Table.AddColumn(カスタム2, "year", each if [age] < 30 then "30歳未満" else "30歳以上")
```

![2020-11-28_10h52_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/40c9e46f-226c-671d-a9df-992828a7f86b.png)

## リストと一致するかの確認

```:リストに一致したらtrueを返す
= Table.AddColumn(カスタム2, "year", each if List.Contains({"Bob", "Tom"}, [name])  then true else false)
```

![2020-11-28_11h00_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/d9c52564-e85c-f012-e2fe-8b1892ac5284.png)

最後に項目のデータタイプを指定することも可能

```:リストに一致したらtrueを返す
= Table.AddColumn(カスタム2, "year", each if List.Contains({"Bob", "Tom"}, [name])  then 1 else 0, type number)
```

指定したい型は、Power Queryで一度変換して作られる関数を見るのが良いです。

# 日付から年月を作成
```
= Table.AddColumn(スタム2, "年月", each Date.ToText([日付], "yyyy/MM"))
```


# 型変換 + Error対応

```
= Table.ReplaceErrorValues(Table.TransformColumnTypes(テーブル, {{"column1", type number}, {"column2", type number}}), {{"column1", null}, {"column2", null}})
```
【Semantic Segmentation】ICNet : ICNetはなぜ速いのか？

<h2>新規性</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/2671c7e4-f341-faf5-9c5a-5fc2466945aa.png)
一番下の段のEncoder-Decoder Modelで精度の良いSegmentationをするのに多くのLayerが必要になる。
これは計算コストが無駄だと考え、1/2,1/4にDownsampleした画像を畳み込み、結合する事で計算量を小さいまま精度の良い結果を得る事が出来る。

紫色の線はTrainning時のみに使われ、Groundと比較してlossをそれぞれのサイズ毎に計算している。このように中間でlossを計算する事により安定したTrainingが行われる事が一般的に知られている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/2fdd79d8-1a99-3011-4cbb-6ae1396866eb.png)

CFF(Cascade Feature Fusion)は図のような設計になっており、紫の線がTraining時に適応されるlossを計算する為のpipelineである。Classifier ConvでSemantic Mapを推定しLABEL(Ground Truth)と比較してlossを計算している。

F1(低解像度)とF2(高解像度)のfeature mapを前処理を行い、足し合わせた後にReLUをすることにより情報の結合を行っている。

*Dilated Conv    =>upsampleしたsparseなFeature MapをDenseにする為の処理
*Projection Conv =>F1とchannel数を一致させる為の1x1 convolution

個人的にはSUMではなくconcatenateした方が精度上がる気がするのだが、計算コストの問題だろうか

<h2>結果</h2>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/3875ebce-9d05-8ab2-3144-fd69681f2f76.png)

精度もそこそこで早い！

<h2>結論</h2>
downsampleしてから畳み込む事でスピードを上げ、高解像度のFeature Mapに足し合わせる事で精度を担保している。

シンプルで速くて精度がそこそこだから実用向きなネットワークだと思うa

<h1>参考文献</h1>
ICNet for Real-Time Semantic Segmentationon High-Resolution Images
https://hszhao.github.io/papers/eccv18_icnet.pdf
CakePHP2で行った拡張子の末尾の値の取得方法

※メモ代わりに投稿させていただきます

画像をViewに表示する先にファイルの拡張子の末尾が必要だったため以下のコードを記述

~~~php:PostsController.php
//登録するファイル名の名前を取得
 $fileName = $this->request->data['Post']['image']['name'];

//substr関数で文字の一部を取得
$extension =  substr($fileName, -3);
~~~

これで「画像.jpg」や「画像.png」の値を抜き出せる
が.jpegみたいな４文字のパターンもある

そこで`pathinfo`関数を利用

~~~php
$extension 
 = pathinfo($fileName,PATHINFO_EXTENSION);
~~~

これで下記でデバックしたらうまくいきました。

~~~php
$this->log($extension, LOG_DEBUG);
~~~
【AWS】用語を整理しながら学ぶAWS - part3


# はじめに

この記事では
AWSのあんなことやこんなことについてまとめた記事です。
ベストプラクティスや間違いがあれば、書き直していく予定です。
今回は
NATゲートウェイの設定
サーバの設定
他、重要な用語について整理してみました。

参考図書：[さわって学ぶクラウドインフラAmazon Web Services 基礎からのネットワーク&サーバー構築](https://www.amazon.co.jp/dp/B084QQ7TCF/ref=cm_sw_r_tw_dp_U_x_-vD5EbQCMD1A9)


--------------------------------
# NATゲートウェイとは

NetworkAddressTranslation
要はアドレスの読み替えです。

> グローバルアドレスからローカルアドレスへの読み替え
> AWSで例えるとパブリックIPからプライベートIPへの変換
> Ciscoなどでは静的か動的かというところまで分かれるのでここでは割愛

よく、インフラエンジニアのお姉さんに
NAPTのことをNATだと注意されましたが
実際のところ、近年ではどちらでも構わないということ

ただし、参考図書にもあるように
ポート変換も含めてアドレスを変換する場合は
NAPT(IPマスカレード)と呼んだほうが正確です。

私と同じようなツッコミを受ける人には使える受け答えかもしれませんね。

ちなみにAWSではNATをする方法として
本記事で紹介しているNATゲートウェイの他に**NATインスタンス**というモノがあります。
お手軽に済ませたいので本稿では割愛

--------------------------------
# NATの良いところ

> 内部のIPアドレスを外向けに公開しないようにできること
> NATされたネットワーク機器のアドレスを隠すことができること

参考図書では
DBサーバを内部ネットワークに配置するとき
DBサーバをインターネットに接続する方法の解説でNATゲートウェイを用いています。

ただし、内部のDBサーバと接続されたサーバが乗っ取られてしまうと
NATの意味がなくなってしまうので
適切なファイアウォールの設定が必要である。

また、今回ではAWSをベースにNATの説明をしているので
あまり関係ないですが、オンプレ環境の装置でNATをかけている場合は
隣接されているL3スイッチやルータのコンフィグレーションが流出しないように気を付けましょう。

--------------------------------
# ファイアウォール(FW)とは

NATのところで名前が出ましたので解説

> 要するに装置を攻撃者から守る防御壁
> いろんなタイプが存在する防御壁

いろんな会社が生産している
ネットワークアプライアンスに必ずと言って良いほど存在する機能

> Ciscoで言えば CiscoASA
> Juniperで言えば SRX
> パロアルトで言えば Palo Alto Networks PA シリーズ
>  Check Pointで言えば..なんだったか
> とりあえず、いろんなところが開発してます。

AWSではセキュリティグループという考え方で
FWを構築できます。

--------------------------------
# NATとFW

アドレス変換したらFWの設定はどうなるのって思いますよね。
ここが重要なポイント
基本的にFWがブロックするのは隣接装置からの
**IPアドレスまたはIPアドレスとサービスを組み合わせた接続をブロック**します。

つまり、NATで変換した通信がFWから見えているのであれば
NAT後のアドレスでFWのセキュリティポリシーを設計しなければなりません。
変換前のアドレスで設計しないように気を付けましょう。

--------------------------------
# サーバの設定

NAT、FWの設定ができたらいよいよサーバの設定
サーバの設定をするときに重要なコマンド
(Amazon Linux 2 ベースで)

> sudo ～
> systemctl enable
> systemctl start
> yum install
> wget [URL]
> tar xzvf [tarファイル名]
> chown

sudo : スーパーユーザードゥー、つまりWindowsでいうところの管理者として実行
systemctl : システムコントロール、利用するアプリケーションを動かす動かさないはこれを使う
yum : パッケージマネージャと呼ばれるモノ
wget : ウェブゲット、指定されたURLからファイルを取得する。
tar : 圧縮ファイル形式 tarを作成・解凍するコマンド
chown : チェンジオーナー、ファイルの所有者/グループを変更する

# コマンド具体例

> sudo amazon-linux-extras install php7.3
訳:管理者権限を用いてamazon-linux-extrasを実行し、php7.3をインストールする。

> sudo yum -y install mariadb-server
訳:管理者権限を用いてMariaDBを強制的にインストールする。

> sudo systemctl start mariadb
訳:管理者権限を用いてMariaDBを起動する。

> sudo systemctl enable mariadb
訳:管理者権限を用いてMariaDBをサーバー立ち上げ時に自動起動するよう設定する。Windowsで言うところのスタートアップ

> systemctl start 後に変更した設定を反映させる場合は
> sudo systemctl restart ～
と打ってください。でないと反映されません。
※ちなみにここで結構ハマりました。

> sudo yum -y install php php-mbstring
訳:管理者権限を用いてphpとphpのマルバイト文字列対応ライブラリをインストールする。


> wget https://ja.wordpress.org/latest-ja.tar.gz
訳:wordpressをダウンロードする。

> tar xzvf latest-ja.tar.gz
訳:latest-ja.tar.gzを解凍する。

> sudo cp -r * /var/www/html/
訳:カレントディレクトリにあるフォルダとファイルを全て/var/www/html/に移動する。

> sudo chown apache:apache /var/www/html/ -R
訳:カレントディレクトリにあるフォルダとファイルを全て、所有者をapacheに変更する。

--------------------------------
# まとめ
- IPアドレスを公開したくない場合はNATゲートウェイかNATインスタンスを使う。
- FWにはいろんな種類が存在するがAWSではセキュリティグループという単位でセキュリティを管理する。
- 一般的にはNATを構築した際は隣接しているFWの設定も見直さなければならない。
- システムの変更をする場合はスーパーユーザー権限を使う。

--------------------------------
# おわり
HSRPをEnbedded Event Manager(EEM)で切り戻す

# はじめに
Cisco機器の**ゲートウェイ冗長化機能**に`HSRP`がありますが、切り替わりはともかく、切り戻す際にはどのように戻していますか？

各案件、各会社のポリシーなどにより、様々なやり方があるかと思います。

- 自動で主系機器に切り戻す
- 手動で主系機器に切り戻す
- 切り戻しはせず、動いている機器側を使う

私が関わっていた案件では、何かしらの問題が生じて切り替わった場合、**原因が判明するまでは切り戻したくない**、また**極力パケットは同じ経路を通るようにしたい**お客様が多かったので、常に優先度が高いルータが選出されるようにする`Preempt`設定はせず、問題解決後、**手動で主系機器に切り戻す**方法をよく行っていました。

ただ、`HSRP`には意図的に切り替えを行うオペレーションコマンドが無いため、切り替えるためには、コンフィグレーションモードでインタフェースを落として切り替えたり、一時的に`HSRP`の`Preempt`設定を加えて切り替えるしかありません。

一時的にでも設定変更するリスクが伴うため、ヒューマンエラーを減らすよう、以前私が使っていた`Enbedded Event Manager`(EEM)による`HSRP`の切り戻しを紹介しようと思います。

# Enbedded Event Managerとは
Cisco機器で使用できる機能で、カスタムコマンドの作成や特定イベント発生時にログ通知するようなことが行えるものとなります。

サーバで言うところのいわゆる**シェルスクリプトによるコマンド実行**にイメージが近いと思います。

※`Feature Set`によっては使えないものもあったと思うので、もし使う場合は事前に調べてください。

# カスタムコマンドの作成
今回は以下の操作を行うコマンドを作成します。

- 指定HSRPグループの設定にPreempt設定を加える
- 5秒待機
- 指定HSRPグループの設定からPreempt設定を削除する

やっていることは手動で行う場合と同様なので、コンフィグレーションモードで一時的に設定変更するのと変わりませんが、カスタムコマンドを作っておけば**管理者モードで実行できる**のと、作業時のコマンド数が減るので**ヒューマンエラーを減らせる**利点があります。

また、主系機器への切り戻しを行うコマンドとなるので、本設定を行うのは**主系となる機器のみ**設定すれば良いです。
※従系機器に入ってても`Priority`が低くて切り替わらないので、あっても問題ないですが。

今回は以下構成を想定してカスタムコマンドを作成していきます。

|項目|設定|
|:--|:--|
|アプレット名|hsrp10failback|
|HSRP適用インタフェース|GigabitEthernet0/1|
|HSRPグループID|10|

## アプレットの作成
`EEM`は`アプレット`ごとに定義を設定でき、各アプレットに複数の処理を設定できます。

今回は`hsrp10failback`という名前のアプレットを作成して、カスタムコマンド用の設定を加えていきます。

「1.x」と書かれている部分は順番を表す数字となり、今回は0.1ずつ増やしていますが、昇順になっていればいくつでも構いません。

```shell:アプレットの作成
event manager applet hsrp10failback
 event none
 action 1.0 cli command "enable"
 action 1.1 cli command "configure terminal"
 action 1.2 cli command "interface GigabitEthernet0/1"
 action 1.3 cli command "standby 10 preempt"
 action 1.4 wait 5
 action 1.5 cli command "no standby 10 preempt"
 action 1.6 cli command "end"
```

尚、コマンド実行時に引数を渡して指定のHSRPグループIDの切り替えを行うといったことは（多分）できないので、複数のHSRPグループが存在する場合は、その分作成しましょう。

## エイリアスの作成
`EEM`を実行する際には`event manager run [アプレット名]`の形式で実行する必要がありますが、長いので、エイリアスを設定して`[アプレット名]`のみで実行できるようにします。

```shell:エイリアスの作成
alias exec hsrp10failback event manager run hsrp10failback
```

設定出来たら、エイリアスを読み込むために一度ログアウト＆ログインしておきましょう。

# HSRP切り戻しコマンドの実行
管理者モードで以下コマンドを実行することで一時的に`Preempt`設定が行われるので、`HSRP`の`Priority`が高い機器へ切り戻されます。

```shell:カスタムコマンドの実行
hsrp10failback
```

# おわりに
大分昔に使っていたやり方なので、もし今もう一度切り戻しツールを作るとしたら`Ansible`などで作ると思いますが、諸々の理由で`Ansible`などのツールが使えないという人のために残しておきます。
Twitter認証の実装でログアウト出来なかったら読んでほしい記事

# 概要
ぐぐっても解決法が見当たらず、
結構ハマってしまったので、同じような人の助けになればと思い記事にします。

# 現象
Twitterログイン系のライブラリを使用して
認証画面にリダイレクトした際に既に連携先のアカウントが自動で選択されている。
そして、ログアウトの機能を呼び出してもログアウトすることができない。

# 解決
端末にインストールしているTwitterアプリでアカウントにログインしていると、
それが影響して自動で認証されるようになっている。
なので、Twitterアプリの方からログアウトすることで解決できます。

自分の開発しているアプリが他のインストール済みアプリから影響を受けているというのは気づきにくいですよね。
正式な仕様やどうしてこうなるかの資料がみたらなかったのですが、
自分のアプリがTwitterからログアウトしても端末レベルで認証されていたらダメということなのかと思います。

詳しい理由や仕組み等ご存知の方がいらっしゃりましたら教えていただけますと幸いです。
nvidia gpuを利用したdockerイメージの作り方、環境構築仕方

2020年の自分のやり方をメモます。dockerコンテナ内にgpuを利用したアプリ実行するため、

- ホスト環境の整備
- ホスト環境に合わせたdockerイメージの作成
- docker起動時に適切な引数、環境変数を与える

が必要です。順に解説していきます

# ホスト環境の整備
自分の環境がubuntu20.04で、これでベースにして説明します。
 
## dockerのインストール
説明割愛

## nvidiaのドライバーのインストール
20.04または18.04の環境において、以下のスクリプトで一発で入れます。

``` bash
$ sudo update-pciids
$ echo -e "blacklist nouveau\noptions nouveau modeset=0" > /etc/modprobe.d/blacklist-nvidia-nouveau.conf
$ sudo update-initramfs -u
$ sudo ubuntu-drivers autoinstall
$ sudo prime-select nvidia
```

終わったら再起動し、nvidia-smiコマンドでgpuが使えているを確認。


## nvidia container-runtime toolをインストール
1. 以下の中身のnvidia-container-runtime-script.shを作成(https://collabnix.com/introducing-new-docker-cli-api-support-for-nvidia-gpus-under-docker-engine-19-03-0-beta-release/ 参照)

``` bash
curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \
  sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list
sudo apt-get update
sudo apt-get install nvidia-container-runtime
```

1. 作成されたnvidia-container-runtime-script.shを実行する。終わったら一旦docker deamonを再起動。

```
$ sh nvidia-container-runtime-script.sh
$ sudo systemctl restart docker
```

1. docker run にgpusオプションがつけるのを確認:

```bash
$ docker run --help | grep -i gpus
--gpus gpu-request               GPU devices to add to the container ('all' to pass all GPUs)
```
1. nvidia-container-runtime-hook実行ファイルがあるのを確認:

```bash
$ which nvidia-container-runtime-hook
/usr/bin/nvidia-container-runtime-hook
```

# ホスト環境に合わせたdockerイメージの作成
nvidia公式dockerhubから自分のosとnvidiaドライバーバージョンに一致したイメージをベースにしてDockerfileを作成：
https://ngc.nvidia.com/catalog/containers/nvidia:cudagl/tags

例えば自分の環境がubuntu20.04でCUDA Versionが11.0なので、nvidia/cudagl:11.0-base-ubuntu20.04　このイメージをベースにします。
Dockerfileサンプル：

```Dockerfile
FROM nvidia/cudagl:11.0-base-ubuntu20.04

# Run a full upgrade and install utilities for development.
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub
RUN apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
RUN apt-get update && apt-get install -y tzdata
# timezone setting
ENV TZ=Asia/Tokyo

RUN apt-get update && apt-get upgrade -y && apt-get install -y \
    mesa-utils
```

このdockerfileを

```bash
$ docker build --network=host -t foo-gpu-image .
```

でbuildします。

# docker起動時に適切な引数、環境変数を与える
先ほど作成したdockerイメージを以下のスクリプトで起動

```bash
#!/bin/bash
xhost +si:localuser:root

docker run  -it --name foo_container --rm  --gpus all \
       --privileged     \
       --env="DISPLAY"  \
       --net=host \
       -e QT_X11_NO_MITSHM=1 \
       foo-gpu-image  /bin/bash
```

で、サンプルのopengl歯車起動

```bash
# glxgears
```

![スクリーンショット 2020-11-28 10-28-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159774/35d77cde-e629-e893-17f9-413d3938c97c.png)

ぐるぐる回れば成功。おめでとう。また、QTアプリ起動する場合に環境変数QT_X11_NO_MITSHM=1 を設定する必要があります。

以上です。

次回を待て！
デモ

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="yuji64" data-slug-hash="JjRojKv" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="JjRojKv">
  <span>See the Pen <a href="https://codepen.io/yuji64/pen/JjRojKv">
  JjRojKv</a> by ゆーじろー (<a href="https://codepen.io/yuji64">@yuji64</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
Xcodeプロジェクトでxib含めて文字列検索したいとき

![Xcode-12.0](https://img.shields.io/badge/Xcode-12.0-brightgreen) 
## はじめに
Xcode プロジェクトで Assets のこの色どこで使ってるんだ？？とか xib, storyboard を含めて検索したいときがあります。しかし！！ Xcode の検索機能だと xib, storyboard までは検索されません。。。（Cutom Class とか検索にヒットするやつもあります）

そういう場合の検索法について書きます。おすすめあったらぜひ教えて下さい。

結論から言うとターミナルで grep　。。。

## 検索するやつ
[GitHub：SampleSwiftApp](https://github.com/adventam10/SampleSwiftApp) このプロジェクトで検索しました（Xcode12 対応したぜ:thumbsup:）。

プロジェクト全体で `WKWebView` の検索をしたいと思います。

## Xcode の検索の場合
Xcode で検索する場合です。

### 方法
左側の検索タブに WKWebView と入力します。

### 結果
<img width="400" alt="xcode" src="https://user-images.githubusercontent.com/34936885/100491079-53f52f00-3164-11eb-8e86-56e77f8fec60.png">

やっぱり storyboard, xib はヒットしません。。。:neutral_face:

## Sublime Text で検索
わたしがよく使ってる方法です。

[Sublime Text](https://www.sublimetext.com/) を使って検索します。

### 方法
1. cmd + shift + F で検索モードにする。
1. Where: にプロジェクトのパスを設定する。
1. Where: に ,*swift,*xib,*storyboard を追加して検索する拡張子を指定する。  
（ライブラリの README とかひっかかることがあるので拡張子指定しといた方が楽）
1. Find: に WKWebView と入力する。

### 結果
<img width="500" alt="sublime" src="https://user-images.githubusercontent.com/34936885/100491090-64a5a500-3164-11eb-8dcf-44250584bf49.png">

storyboard, xib もちゃんとヒットしています:tada:ヒットした箇所周辺の行も表示してくれます。

## grep コマンド
ターミナルで grep する方法です。

### 方法
ターミナルで下記コマンドを実行する。

```
$ grep -ir --include='*.swift' --include='*.xib' --include='*.storyboard' "WKWebView" <プロジェクトパス>
```

### 結果
<img width="500" alt="grep" src="https://user-images.githubusercontent.com/34936885/100491106-78510b80-3164-11eb-8605-3ded47ba492b.png">

storyboard, xib もちゃんとヒットしています:tada:もうちょっと見やすく表示する方法はあるかもしれない:thinking:

## ag コマンド
Twitter で教わったのですが ag コマンドっていうのがあるらしいです（とにかく速いらしい:rocket:）。  
参考：[The Silver Searcher のススメ](https://qiita.com/thermes/items/e1e0c94e2875df96921c)

### 方法
ターミナルで下記コマンドを実行する。

```
# インストール
$ brew install the_silver_searcher

# 検索（wkwebview と小文字で指定する）
$ ag -G '\.(swift|xib|storyboard)' wkwebview <プロジェクトパス>
```

### 結果
<img width="500" alt="ag" src="https://user-images.githubusercontent.com/34936885/100491117-830ba080-3164-11eb-867b-bab604e7bad8.png">

storyboard, xib もちゃんとヒットしています。色が着いててみやすい:clap:

## おわりに
さくっと Xcode で検索したいけどあきらめて他のやつを使った方がよさそう。

他におすすめの方法があったらぜひ教えて下さい:pray:
Spring Data RedisのRedis Repositoriesの制約

# Redis Repositoriesとは
> Working with Redis Repositories lets you seamlessly convert and store domain objects in Redis Hashes, apply custom mapping strategies, and use secondary indexes.

https://docs.spring.io/spring-data/redis/docs/current/reference/html/#redis.repositories

Sprint Data Redisの機能の1つで、JavaオブジェクトとRedis Hashをシームレスに出し入れ出来るのと、インデックスの管理をやってくれる便利なものです。

# 制約
保存するときにトランザクション無しにdelete & insertするので（上書き保存しないので）、タイミングによってキーが無いように見えます。保存と読み込みを高頻度でやると再現します。

# ソースの該当箇所
L234-236

```RedisKeyValueAdapter.java
			boolean isNew = connection.del(objectKey) == 0;

			connection.hMSet(objectKey, rdo.getBucket().rawMap());
```

https://github.com/spring-projects/spring-data-redis/blob/master/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java

# 結論
上記の制約を理解して使うか、Redis Repositoriesを使わないのいずれかと思います。

# 追記
13.9. Persisting Partial Updates
https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/#redis.repositories.partial-updates
を使うといいよ、というアドバイスをいただいた。
https://jira.spring.io/browse/DATAREDIS-1253

”JavaオブジェクトとRedis Hashをシームレスに出し入れ”とは言えないが、インデックスは更新されるので、INSERTはsave、UPDATEはpartial updatesのように使い分けるといいかも知れない。

同じ問題でハマっている人を見つけて、同じアドバイスをもらってた。
https://stackoverflow.com/questions/48116466/update-entity-in-redis-with-spring-data-redis
Progate　JavaScript　II

Progate
・JavaScriptII

繰り返し、配列、オブジェクト等
上記の内容でしたが、こちらもPHPと類似点が多い印象でした。
バッククォーテーションを用いたテンプレートリテラルは忘れてしまいがちなので意識していきたいです。
while文、for文、swich文はほぼPHPと同じ。
配列とオブジェクトは初感覚でした。
応用問題は、変数（定数）.プロパティ　を用いた処理を忘れずに行いたいです。
ただ、基礎の組み合わせなので難しくはないですね！
ファイルタイプと文字化けした時の対処法inMac

# 概要
ファイルを開いて、、
→�x�����v

！？？？？、なんだこれ・・・？
となった人に向けた記事になります。

この問題の対処の方針は２段階で
1,まず文字コードを確認する(動く方と動かない方)
2,文字コードを変更する。
でなんとかできます。

#1, 文字コードを確認する
下記コマンドで文字コードを確認します

```
// hoge.csvの文字コードを確認する
file --mime hoge.csv
```
こんな感じの結果が出力されます。
unknown-8bitはShift-JISのことです。

hoge.csv: text/plain; charset=unknown-8bit
hoge.csv: text/plain; charset=utf-8

正しいファイルの文字コードと間違っているファイルの文字コードが確認できたら、
次のステップのコマンドにより文字コードを正しく修正します。

#2, 文字コードを変更する
文字コードを変更するにはnkfコマンドを使用します。
オプションにより、変換後の文字コードを決めることが可能です。

```
//　文字コードをUTF-8に変換　-wオプション
nkf -w --overwrite hoge.csv

// 文字コードをShift-JISに変換 -sオプション
nkf -s --overwrite hoge.csv
```

# 終わりに
どうだったでしょうか・・・？
使いたいファイルが文字化けしてるとびっくりしますよね。
そんな時も焦らず対処しましょう！
nginxでproxy_passでリバースプロキシする際に日本語が含まれてるパスがうまく行かなかったときの解消メモ

開発中にハマったのでメモ

# 状況

以下のようにアプリとS3のファイルを同一ドメインで見られるようにしたかったのでnginxで制御しました。

* /images/* ならS3のバケット内を参照
* 上記以外ならアプリを参照

```conf:nginx.conf
  (省略)
  location / {
    proxy_pass http://127.0.0.1:3000; # 通常パスはアプリを見る
  }

  location ~ ^/images/(.+)$ { # 画像パスはS3を見る
    resolver 8.8.8.8;
    set $s3_path "s3のバケット名.s3.amazonaws.com";
    proxy_pass http://$s3_path/images/$1;
  }
  (省略)
```

これでうまく表示できていたのですが、`/images/日本語.jpg`といったようなマルチバイト文字を含むファイル名に対して、
`http://domain/images/%E6%97%A5%E6%9C%AC%E8%AA%9E.jpg`というようなパスでアクセスしてもS3の403が帰ってきました。

# 解決法

以下のようにファイルパスを一度変数にして向き先を指定

```conf:nginx.conf
  (省略)
  location / {
    proxy_pass http://127.0.0.1:3000; # 通常パスはアプリを見る
  }

  location ~ ^/images/(.+)$ { # 画像パスはS3を見る
    resolver 8.8.8.8;
    set $s3_path "s3のバケット名.s3.amazonaws.com";
    set $file $1; # マッチしたパスを変数に格納
    proxy_pass http://$s3_path/images/$file; # 変数化したパスを指定
  }
  (省略)
```

これで表示できるようになりました。
ただ、なぜこれでうまくいくようになったのかが分からず…
FullCalendarでドラッグ&ドロップで日付を変更する

fullcalendar祭りです。

【技術スタック】
- Laravel 6.0
- AdminLTE 3 (ComposerでLaravelにインストール)
- jQuery 3.3.1+ (AdminLTEにデフォルトで入っている)
- FullCalendar 5.3.2 (AdminLTEでデフォルトで入ってるのは古いので別途新しいバージョンをCDNで導入)
- moment.js (CDNで導入)

## 全体の大まかな流れ

1. カレンダーのイベントをドラッグ&ドロップする
2. イベントの **id** と **日付(ドラッグ&ドロップした後)** を取得して、AjaxでコントローラーにPOSTで取得した値を送る
3. コントローラー側で、JS側から送られてきた値でレコードを更新して、saveする

気になる部分をかいつまんでいきます。

```js
document.addEventListener("DOMContentLoaded", function () {
  var calendarEl = document.getElementById("calendar");
  var calendar = new FullCalendar.Calendar(calendarEl, {
    headerToolbar: {
      left: "prev,next today",
      center: "title",
      right: "dayGridMonth,timeGridWeek,timeGridDay,listWeek",
    },
    locale: "ja",
    editable: true,
    googleCalendarApiKey: "GoogleCalendarのAPIKEY",
    eventSources: [
      {
        googleCalendarId: "japanese__ja@holiday.calendar.google.com", //休日の予定を取得
        rendering: "background",
        color: "#FF6666",
      },
      {
        googleCalendarId: "自分のカレンダーID",
      },
    ],
    events: "/getevents",
    selectable: true,

    eventDrop: function (info) {
      $.ajax({
        //POST通信
        type: "post",
        //ここでデータの送信先URLを指定します。
        url: "/dropevents",
        dataType: "json", //データ形式を指定
        data: {
          dropped_date: moment(info.event.start).format("YYYY-MM-DD"), //dropped_dateをキーにして値を送信
          id: info.event.id, //idをキーにして値を送信
        },
      }).then((res) => {
        console.log(res);
        calendar.render();
      });
    },
  });
  calendar.render();
});
```

```php
// コントローラー側
  public function getEvents() // イベントの取得
  {
    // user_idを持たせておく
    $data = [];
    $authUser = Auth::user()->id;
    $events = Event::where("user_id", "=", $authUser)->get();
    $data = $events;

    echo json_encode($data);
  }

  public function dropEvents(Request $request) // ドラッグ&ドロップしたときの挙動
  {
    $event = Event::find($request->id); // JSから送信されたidで該当イベントを検索
    $event->start = $request->dropped_date;
    $event->save();
  }

```

- カレンダーの予定は、`events: "/getevents"`で取得しています。
- `eventDrop: function (info)`で、ドラッグ&ドロップしたときの挙動を表しています。この時にAjax通信をしています。
- ドラッグ&ドロップすると、
` data: {
          dropped_date: moment(info.event.start).format("YYYY-MM-DD"),
          id: info.event.id,
        }`の値がコントローラーに送信されます。
DBの日付のフォーマットが`YYYY-MM-DD`なのに対して、カレンダーから送信される値は`Fri Nov 20 2020 00:00:00 GMT+0900 (日本標準時)`という形式なので、moment.jsで`YYYY-MM-DD`形式に整形しています。
- `calendar.render();`でカレンダーを再描画しています。

予定「あああああああ」を、20日に動かすと・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499375/e050c763-f394-05d1-1359-28acacc6cfb6.png)

リアルタイムでDBの値が更新され、ページリロードしなくても予定が20日に移動していることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499375/1f0eb5fb-83d0-06cf-0dc2-b3c853c2667c.png)
【Nuxt.js】Vue CLIによりアプリケーション雛形を作るまで

![スクリーンショット 2020-11-28 10.00.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620533/7c4a0d29-5f31-770c-1cec-617d1bd70ded.png)

言語化するために記事に起こしました。
汎用性の高いスターターテンプレートで雛形を作成するまでを簡潔に記します。

#事前準備
①Node.jsの導入
②Yarnの導入
③direnvの導入

①、②共にNuxt.jsで開発する上で必須となるので導入する（ここではこれらの導入方法については省略します)。

③はターミナルのcurrentディレクトリで環境変数を自動で設定してくれるツール。環境変数の設定忘れを防止するため導入するとよい。

#1
```ruby:ターミナル
npm i -g @vue/cli @vue/cli-init
```
上記コマンドで、Vueコマンドを追加する。「Vue -V」でバージョン確認。

```ruby:ターミナル
$ vue -V
  @vue/cli 4.5.9
```
#2
1により、「vue init」コマンドでプロジェクト作成可能。
今回は初学者やカスタマイズして利用したい方におすすめのテンプレートである、「my-first-nuxt-app」を利用する。

```ruby:desktop
$ vue init nuxt-community/starter-template my-first-nuxt-app
```
インストール中のいくつかの質問は全てEnterでOK。
作成後、

```ruby:ターミナル
$ cd my-first-nuxt-app #ディレクトリに移動
$ yarn #パッケージをインストール
$ yarn dev # 開発モードでプロジェクトを起動
```

OPEN http://localhost:3000
と表示後、上記URLにアクセスする。

#3
![スクリーンショット 2020-11-28 10.00.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620533/d9a13261-4f29-fe65-166e-9995f074424a.png)

このような表示が出れば完了です！
僕のための最強の技術メモの作り方

僕がここ数年続けている技術メモの書き方をまとめていきます。
技術メモ自体はみんながやっていて、それぞれのやり方があると思いますが、
自分なりのやり方がある程度固まってきたので、ここで共有したいと思います。

これをやっていくと、**僕の僕による僕のための最強の技術メモが出来上がってきます。**

## 使用するツールについて

社内で情報共有するツールとして、esa、QiitaTeam、Notion・・などいろいろありますが、
ここでは自分だけのための技術メモの書き方を共有します。

したがって、以下のツールがあれば十分です。

- VSCode
- Git（GitHub）

## 実際にどうまとめているの？

実際にVSCodeで、以下のような感じで管理しています。

![スクリーンショット 2020-11-28 9.54.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113289/443dab5b-8de9-8a3b-c893-bf146f25940d.png)

例えば、Rubyというフォルダの中に、Rubyに関連するメモをまとめています。資格試験の勉強の時に結構書いたので、Rubyのとこは比較的充実してます。
その中で、rbenv.txt について表示していますが、rbenvに関するインストール方法、アップデート方法など、rubyのバージョン管理方法についてまとめています。

## カテゴリごとにフォルダでわける

カテゴリごとにフォルダを作成して、検索しやすいようにしています。
内容によっては複数カテゴリにまたぐこともありますが、
自分がひっかけやすい方のフォルダに入れます。


## 自分にわかりやすいように書く

メモは自分しか見ないものなので、自分にわかりやすいように書きます。
社内で共有するメモは、誰が見ても理解できるに書くことを意識すると思いますが、
自分がわかれば良いというレベルで書きます。
つまり、**自分がわかりきっている内容は省略して書きます。**

メモをまとめ始めると意外と時間を取られるものですが、
上記のようにすることで時間を短縮できますし、メモを書くハードルがグッと下がります。


## 学んだタイミングですぐ書く

新しいことを学んだら、すぐにメモを書くことを意識しましょう。
後に回すと絶対にまとめません。（ソースは自分）


## 内容は間違っていても良い

メモは自分しか見ません。**間違えて恥ずかしい思いをすることがありません。**
なんかよくわからんけどこういうことかな？ぐらいの意識で問題ないので、
とにかく書きましょう。


## 無理のない量にする

とはいえ、とにかくメモを書けば良いというものではないです。（どっちやねん）
教科書を写経のように書いて、理解しきれていないことをまとめても仕方がないです。

**タイトルをつけて、その下に箇条書きぐらいがちょうど良いと思っています。**


## 技術メモはGitで管理する

Gitで管理することで、**技術メモをまとめるモチベーションにもつながります。**
適度なところでコミットし「あぁ、こんなにまとめたんだな〜」って思うことで継続的にやっていくことが出来ます。

また、GitHubなどを利用することで、どこでも見れるというメリットにも繋がります。
ただし、**技術メモに機密情報やパスワードなどを記載する場合は十分に注意しましょう。**

実際に私も自分の技術メモはGitHubで管理していますが、
内容はあくまで技術だけにとどめて、機密情報などは含めないようにしています。


## テキストで書く（マークダウン等は使用しない）

**パット見で確認する情報量としては、やはりテキストが最強です。**
きれいにまとめて印刷とかするわけではないので、
マークダウン等を使う必要はないかなと思います。この辺はお好みですが・・。

私も最初は、マークダウンでまとめようと思いましたが、
後で見たときの情報量が少なくてやめました。
ただ、見出しとか箇条書きとかはマークダウン記法を意識して書いてます。


## 最後に

皆さんのメモライフの参考になればと思います。
他にも自分はこうやってメモしてますーとかあれば、コメント頂けるとうれしいです。
git bashでjqコマンドが使えない時の対処方法

私はWindow10からGitBashを利用しています。
作成したshellファイル中でjqコマンドが実行されませんでした。
ここに調べた対処方法を紹介しておきます。

# 発生したエラー

```bash
bash: jq:command not found
```

# 対処方法

### jq file Download

Macとかlinuxユーザなら多分必要ないです。
まず、
[./jq公式サイト](https://stedolan.github.io/jq/)
こちらから、ファイルを自分の好みの場所にダウンロードしてください。
**jq-win64.exe**というファイルがダウンロードできます。


### alialコマンドでjqコマンドを登録します。

#### bashrc or bash_profileがない場合

alialにjqコマンドを登録する為には **.bashrc**が必要です。
私は .bashrc　がなかったので、作成しました。作成方法は

```bash
$ touch ~./bashrc
```

現在のdirにファイル作成後、bashを再起動すると
最初警告がでます。この警告は**bashrc*を読み込む**bash_profile**が見つからなかったので、作成しましたという意味です
ls -a でリスト確認したら、上記の二つのファイルが作成されていることが確認できます。

#### aliasにjqコマンド登録

```bash
$ alias jq=/path/jq-win64.exe
$ alias
 alias jq=/path/jq-win64.exe
```

上記コマンドで登録後、Listを読んで入っているか確認します。/path/のどころにはwin64.exeがある場所を前に指定してください。
pwd打ったら、確認できます。

#### jqコマンド実行確認

```bash
$ echo '{"check: 1"}' | jq
{
  "check": 1
}
```
これで実行確認完了。

お疲れ様でした。

##参考URL

[Windowsでgitbashからjqを実行するには?](https://www.366service.com/jp/qa/dfffd4dfceba46feb781c002c759e72e)
spock　テスト設計で超絶役に立つマニュアル

結論から申し上げるとGitHubにありました。
リンクが切れたり、GitHubアカウントが消されることも懸念して、時間があるときにこの記事に写しますmm

https://github.com/yamkazu/spock-workshop/blob/master/docs/04_mock.md

>staticメソッドってMock化できるの？


>spock使い方わからない

って人は見てみるとよさげです(*´ω`*)


ちなみに、

Mockitoを使用してプライベートメソッドをモックすることはできません。しかし、明示的な必要性がある場合は、PowerMockを試してみることができます。

パブリックメソッドのテストを書くときにカバーされるので、プライベートメソッドのテストを書くことはそもそも期待されていません。