OmniAICreator/Qiita-1.07M huggingface dataset:
いい感じに「できません」を伝える技術

# 前提

- ここで言う `「できません」` は `「これを断らないとプロジェクトが炎上してしまう」` というようなケースを想定したものです
- どちらかというと他責思考寄りの方に見て頂きたいものであり、自責思考の強い方にはあまりおすすめしません

# はじめに

## 「できません」がうまく伝わらなかったために炎上したプロジェクトは星の数ほどある

- `「できません」と言えない` ために炎上したプロジェクト
- `「できません」と言ったものの聞き入れてもらえなかった` ために炎上したプロジェクト
- `「できません」と言って聞き入れてもらえない中で踏ん張ったものの、結局受け入れてもらえなかった` ために炎上したプロジェクト
- etc...

## 「できません」と言えない、あるいは言っても聞き入れてくれない顧客や上司たち

- このような言葉が日々当たり前のように飛んでくる
    - 「もう決まってるから」
    - 「言い訳はいいんでやってください」
    - 「なんでできないの」
    - 「できるって言ったじゃないですか」
    - 「口動かさないで手を動かして」
    - etc...

## 果たして10:0で相手が悪いのか

- 相手の立場で考えたか
- 「理解してもらう」ための手は尽くしたか
- 「できません」だけでなく「こちらはどうでしょう」と言えるような案はなかったか
- こちらだけが持っている情報はなかったか
- etc...

# いい感じに「できません」を伝える

## 要点

- 聞く耳を持ってくれる可能性を少しでも上げる
- 「Noの承認」から別のテーマに置き換える
- 一緒に課題解決する

## 技術1. 相手の言い分の意図を受け入れる

- 「おっしゃる通りこれはいついつまでにやっておきたいですね」という言葉を添えることで、実現可能性を前向きに検討している姿を示す

## 技術2. 「できない理由」でなく「どうすればできるか」から伝える

- 「できる限り要望に応えたい」という誠意を示す
- 最終的に「できない理由」に行き着くとしても、前向きな話から始める

## 技術3. 口頭だけでなく、可視化された文章も添える

- 「できない理由」は複数の要員が絡み合っていることが多く、口頭だけで説明しても伝わりきらない
- 「わからないから認めない」という状況を回避する

## 技術4. 代替案をセットで提示する

- 「できない」を伝えたあとに出てくる「じゃぁ何ならできるの？」を相手からでなく、こちらから提示する

## 技術5. 相手に求める回答形式を選択式にする

- 「○○はできません。どうしましょうか？」より「○○はできないので、××か△△か□□のいずれでどうでしょうか？」のほうが前向きな回答の可能性が高い
- 「ちなみに、私はこうしたほうが良いと思っています」も入れておくとさらに前向きな回答になる可能性が上がる

## おさらい

- **「できません」を伝える際に確認しておきたいチェックシート**
    1. [ ] 相手の言い分の意図を受け入れていることを伝えようとしているか
    2. [ ] 「できない理由」でなく、「どうすればできるか」から始まっているか
    3. [ ] 口頭だけでなく、可視化された文章も添えているか
    4. [ ] 代替案をセットで提示しているか
    5. [ ] 相手に求める回答形式を選択式にしているか

# 「聞き入れてくれない顧客や上司」に立ち向かう時に持っておきたい心構え

## 心構え１. 転職という選択肢は常に頭に入れておく

- いわゆる「いい会社[^1]」になればなるほど「聞き入れてくれない顧客や上司」と関わる機会は少なくなるので、無理に悩むより転職してしまったほうが早い

## 心構え2. ただし、「聞き入れてくれない顧客や上司」はどこにでもいる

- 転職は頭に入れておきたいが、「聞き入れてくれない顧客や上司」はどこにでもいるということは頭に入れておいたほうが良い
    - いわゆる「いい会社[^1]」になればなるほど生息確率は減ってくるだろうが、それでもゼロになることはなかなかない

## 心構え3. 聞き入れてくれない状況の多くは「無知」であるために発生している

- 状況を諸々理解したうえで無理難題をあえてふっかけてくるような人はいるものの、状況を正しく理解してもらえれば聞き入れてもらえるケースもそれなりにある

## 心構え4. 体系的に考え他人事化し、自分の心と身体を守る

- 「聞き入れてくれない顧客や上司」はしばしば心を抉るような言葉を投げかけてくるが、そんな言葉を一つ一つ真に受けていたら心も身体も持たない
- 体系化することで、効率化などの観点のほかに「良い意味で自分を他人事化できる」メリットもある

## 心構え5. 「ここまでやってだめなら諦める」という線を決めておく

- どんなに頑張っても聞き入れてくれない人はいるし、諦める(辞めるなり交代させてもらうなり)ことも肝心
- あらかじめ諦める境界線を決めておくと多少心が楽になるかもしれない

## おさらい

- **「聞き入れてくれない顧客や上司」に立ち向かう際に確認しておきたいチェックシート**
    1. [ ] 転職という選択肢は常に頭に入れておく
    2. [ ] ただし、「聞き入れてくれない顧客や上司」はどこにでもいるということも頭に入れておく
    3. [ ] 聞き入れてくれない状況の多くは「無知」であるために発生している
    4. [ ] 体系的に考え他人事化し、自分の心と身体を守る
    5. [ ] 「ここまでやってだめなら諦める」という線を決めておく

# さいごに

みんなが同じ方向を向いてたらそもそもこんなことにはならないと思いますが、本当に難しいですね。
　`「連帯責任」` という言葉をアップデートしていい感じに再定義したい(思いつき)。

[^1]: 主語が大きすぎてあまり使いたくない表現でしたが、ここでは「HRTという言葉を大切にしている会社」という文脈という文脈で記載しています
図解: CentOS 7 の cron / anacron 関係図 ( フロー図 )

# はじめに
　CentOS 7のcron、anacronの関係がややこしくて混乱したので、これらの関係（フロー）と対応する各種ファイルについて1枚の図にまとめてみました。
　anacron自体の動作もややこしいのですが、以下のリンク先にとても解りやすい記事があります。

[@ohtsuka1317] [細かすぎて伝わらない anacron の挙動](https://qiita.com/ohtsuka1317/items/b89ea66f3d227c172477)

# cron / anacron関係図 (フロー図)
![cron-anacron-run-parts.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643108/147700db-8083-25f2-bb08-9dded18807b9.jpeg)
図をクリックして拡大


# 参考資料
[Qiita][@ohtsuka1317][細かすぎて伝わらない anacron の挙動](https://qiita.com/ohtsuka1317/items/b89ea66f3d227c172477)
[man 8 cron](https://www.unix.com/man-page/centos/8/crond/)
[man 1 crontab](https://www.unix.com/man-page/centos/1/crontab/)
[man 5 crontab](https://www.unix.com/man-page/centos/5/crontab/)
[man 8 anacron](https://www.unix.com/man-page/centos/8/anacron/)
[man 5 anacrontab](https://www.unix.com/man-page/centos/5/anacrontab/)
[man 8 run-parts](https://www.unix.com/man-page/Linux/8/RUN-PARTS/)
Gitコマンド集

#記事について
前回gitを使う上での基礎知識をまとめたので、今回はgitのコマンドを記事にしました!

https://qiita.com/masarumosu/items/b954d9755c8d028d2369

##コマンド
####コマンド ---local編
以下のコマンドはgitをローカルで使用する際に、知っておくべき基礎知識です!
仕組みさえ覚えてしまえば、とても便利なのでぜひ覚えましょう💪

```
①  git init      ⑥  git log
②  git add       ⑦  git rm
③  git commit    ⑧  git branch
④  git status    ⑨  git checkout
⑤  git diff      ⑩  git reset
```
####① git init
git initはローカルリポジトリを新規作成するコマンドです。
自分がバージョン管理したいワークスペースのルートディレクトリで、git initコマンドを使用することでルート直下に.gitディレクトリを作成します。.gitディレクトリによって親ディレクトリとディレクトリ内のソースをgitで管理することができます。
*既に.gitが存在する場合は初期化されてしまうので注意！

####② git add
git addは指定したソースをインデックスに登録するコマンドです。
gitでファイル等の変更履歴を保存するためには③git commitコマンドを使用しますが、③のコマンドを使う前にあらかじめ、git addでステージングする(インデックスに登録すること)ことが必要です。
git add <オプション>のようにオプションを指定して使用する。

###③ git commit
git commitは②のgit addによってステージングされたソースの変更履歴を保存するコマンドです。
コマンドを使用するとテキストエディタが起動し、変更履歴にメッセージを残せます。
git commit -m"ファイルを変更"のように、引数に-m"メッセージ"を与えるとテキストエディタを開くことなくcommitできます。

###④ git status
git statusはバージョン管理の状態を確認できます。以下は具体的な内容です。
・git add されているけどまだ git commit されていないファイルの一覧
・編集・変更・削除されているが、まだ git add されていないファイルの一覧
・Git管理されていない、かつ .gitignore で管理除外対象にもされていないものの一覧
*引用　https://qiita.com/tommy_aka_jps/items/af536a7c20747f99aa42

###⑤ git diff
git diffは指定した指定した2点間の変更差分を確認できます。
commit同士、同ファイル、ブランチ間等、指定できるオプションは多岐に渡ります。


###⑥ git log
git logは現在までのcommit履歴を確認できます。
commit履歴には、以下の情報が含まれています。
・originのurl
・現在の場所
・コミットID
・作成者
・メッセージ
git logを確認し、コミットIDから過去のバージョンに戻すことができます。
![qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025549/137b9768-acf0-6422-cf73-cae672affaa2.png)

###⑦ git rm
git rmとは指定されたファイルを削除し、リポジトリからも削除するコマンドです。一度commitされたファイルをただ削除するだけでは、リポジトリから削除されません。その為、削除され表示されていないファイルがリポジトリ上に残っており、エラーが生じることがあるので気をつけましょう。

###⑧ git branch
git branch <branch名>はブランチを作成することができます。
ブランチ名を与えることなく使用すると、現在存在するブランチを確認することができます。

###⑨ git checkout
git checkout <ブランチ名>はブランチを切り替える為のコマンドです。
コミットしていない変更履歴が存在する場合は、エラーが生じるのでコミットかスタッシュ(一時的にデータを保持する)を行ってから切り替えましょう。
git checkout -b <ブランチ名>でブランチの作成と切り替えを同時に行えます。　

###⑩ git reset 
git resetとは、名前の通り現在の状況をリセットすることのできるコマンドです。
git resetのオプションには以下の三種類が存在します。

```
git reset --soft
git reset --mixed
git reset --hard
```
####git reset --soft
commit履歴をリセットします。
ワークススペースとインデックスは保持されます。

####git reset --mixed
commit履歴とインデックを削除します。
ワークスペースは保持されます。

####git reset --hard
commit履歴、インデックス、ワークスペースを削除します。(つまり前回のcommit地点に戻る)

以上のようにgit resetはsoft--mix--hardの順に削除範囲が広くなります。

##最後に
今回はgitコマンドについてまとめました。私自身もまだ使いこなせてないですが、実際に使用することで少しづつ慣れていきます。次回はgithubについて記事を書きますので、興味があれば参考にしてみてください！
日付フィールドのカラム定義のベストプラクティスを求めて

古いデータベース設計をみると

- year 4桁文字列
- month 2桁文字列
- day   2桁文字列

みたいな、カラム定義をみることがある。

Web系エンジニアからみると「ぞっとする」設計だとは思う。なぜDATE型を使わないのだと。ただ今どきのアーキテクチャでも、DATEとDATETIMEが存在する。本来ならUNIXタイムスタンプですべてカバーできていいはず。時刻は切り捨てて日付だけのフィールドがあるのなら、月単位、年単位のフィールドを切り出す正義もある。

結論はシンプルで、世の中の経済活動の大半は、月別・年別に集計されるから。そしてRDBは計算値フィールドにはインデックスが貼れない（コメント注：今どきのDBMSは貼れる機能が網羅されてきました！）ので、別のカラムとして保存する必要がある。年別にグループ化も一発だ。DATE_FORMAT関数使えば自由に年月日を切り出すことも可能だが、計算値フィールドでグループ化はお行儀は悪い（コメント注：これも式でインデックスを作れる）。

あと、すんごい地味な話として、timestampってタイムゾーンによって日付が変わる。それが便利な時もあれば、そうでない時もあって、あえて日付を文字列で保存することで、「タイムゾーンからの影響は受けないシステムなのだ！」という意思表示をすることもある。
JAVA JPAのN+1問題について

# GOAL
JAVAでDBMSを操作するためにJPAを使用する際に頻繁に発生する「N+1問題」の発生原因及び解決策の基本を知る。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [N+1問題とは](#Chapter1)
1. [原因](#Chapter2)
1. [解決策](#Chapter3)
1. [最後に](#Chapter4)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# N+1問題とは
以下のようなEntity, Repositoryがあるとしましょう。

```java
@Entity
public class Teacher {

    @Id
    @GeneratedValue
    private long id;

    @OneToMany
    private List<Student> students = Lists.newArrayList();
}
```
```java
@Entity
public class Student {

    @Id
    @GeneratedValue
    private long id;

    @ManyToOne
    private Teacher teacher;
}
```
```java
public interface TeacherRepository extends JpaRepository<Long, Master> {

    //JpaRepositoryを継承しているため、デフォルトのメソッドは入っている

}
```
TeacherRepository.findAll()を実行すると以下のようなクエリが発行されることを期待するでしょう。

```
SELECT * FROM Teacher
LEFT JOIN STUDENT
ON STUDENT.TEACHER_ID = TEACHER.ID
```
でも実際のクエリを確認すると以下のように
TEACHERを取得するクエリ → 1回
各TEACHERのSTUDENTを取得するクエリ → N回
のクエリが発行され、「N+1問題」が発生してしまいます。
TEACHERの数が多い場合、パフォマンスに致命的な影響を与えることになるでしょう。



```
SELECT * FROM TEACHER //1回目のクエリ

SELECT * FROM STUDENT WHERE TEACHER_ID = 0 //2目のクエリ
SELECT * FROM STUDENT WHERE TEACHER_ID = 1 //3目のクエリ
SELECT * FROM STUDENT WHERE TEACHER_ID = 2 //4目のクエリ
SELECT * FROM STUDENT WHERE TEACHER_ID = 3 //5目のクエリ
・・・・
SELECT * FROM STUDENT WHERE TEACHER_ID = N  //N+1目のクエリ
```
<a id="#Chapter2"></a>
# 原因
JPAから提供しているメソッドはDBにダイレクトにクエリを発行するのではなく、JPQLというオブジェクト指向クエリ言語を生成・実行してからJPAがこれを分析し、SQLを生成してクエリをDBに発行する動きになっているからです。
上記の例の場合の詳細な動きは以下のようになる。

1. select o from Order o JPQLを分析し、 select * from Teacher SQLを1回発行する
2. SQLの結果に基づいてTeacherオブジェクトを生成する。
3. TeacherのStudentオブジェクトを取得するために、SELECT * FROM STUDENT WHERE TEACHER_ID=? SQLをN回発行する

<a id="#Chapter3"></a>
# 解決策
**join fetch適用**
カスタムレポジトリを作成してJPQLにてfetch明記すれば問題は簡単に解決できます。
select m from Teacher m join fetch m.students
上記のように明記すると、以下のようなSQLクエリが発行されるようになります。

```sql
SELECT * FROM TEACHER
LEFT JOIN STUDENT
ON STUDENT.TEACHER_ID = TEACHER_ID
```
しかし、join fetchをすることにより、以下のようなデメリットが生じます。
・一発で全てのオブジェクトを取得するため、ページング単位で取得ができなくなり、ページング機能の実現が難しい。
・不要なクエリが増える。

<a id="#Chapter4"></a>
#最後に
当記事ではJPAの「N+1問題」の基本を紹介しているため、
LazyFetch、EagerFetchのようなFetch戦略に関して詳しく説明していないが、「N+1問題」をきちんと理解するためには必須知識であるためFetch戦略は他の記事を参考にしてください。
[AtCoder] 競プロ典型 90問 046 - I Love 46

https://atcoder.jp/contests/typical90/tasks/typical90_at

46って出題者はおひさまなんでしょうか。
影山優佳さんサッカー詳しくていいですよね。
問題ですが、3つの整数の和が46の倍数ということは、
3つの整数それぞれの46の剰余の和も46の倍数である必要があります。
ここで3つの整数 $0 \le l,m,n \le 45$ があり、 $l+m+n$ が46の倍数であるとき、
$A_{i} = l, B_{j} = m, C_{k} = n$ となる整数の個数をそれぞれ $\acute{A_{l}}, \acute{B_{m}}, \acute{C_{n}}$ とすると、
選び方は $\acute{A_{l}} \times \acute{B_{m}} \times \acute{C_{n}}$ となります。
その計算をソースコードに落とし込んだのが以下です。
言語はC++(GCC 9.2.1)でAtCoderのコードテストで確認しています。

```c++
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int main() {
  ll N, a;
  vector<ll> A(46, 0), B(46, 0), C(46, 0);
  cin >> N;
  for (int i = 0; i < N; i++) {
    cin >> a;
    A[a % 46]++;
  }
  for (int i = 0; i < N; i++) {
    cin >> a;
    B[a % 46]++;
  }
  for (int i = 0; i < N; i++) {
    cin >> a;
    C[a % 46]++;
  }

  ll ans = 0;
  for (int i = 0; i < 46; i++) {
    if (!A[i]) continue;
    for (int j = 0; j < 46; j++) {
      if (!B[j]) continue;
      for (int k = 0; k < 46; k++) {
        if (!C[k]) continue;
        if ((i + j + k) % 46 > 0) continue;
        ans += A[i] * B[j] * C[k];
      }
    }
  }
  
  cout << ans << endl;
}
```
DockerでTensorFlowがインストール済みのJupyter Lab環境を作る

# はじめに
Python、AI初心者な自分がAI関連の部署に異動になりました。
勉強のため、まずは環境を作ろうと思ったため、`Docker`で`TensorFlow`インストール済みの`Jupyter Lab`の環境を作ったので備忘録を残します。

* [GitHub](https://github.com/h-ueno2/docker-jupyter)

# Dockerfile

```dockerfile
FROM jupyter/datascience-notebook
USER root

RUN pip3 install --upgrade --no-cache-dir \
  tensorflow \
  jupyterlab-lsp \
  'python-language-server[all]' \
  jupyterlab_code_formatter \
  && rm -rf ~/.cache/pip \
  && jupyter labextension install \
  @ryantam626/jupyterlab_code_formatter \
  @krassowski/jupyterlab-lsp \
  && jupyter serverextension enable --py jupyterlab_code_formatter
```

# docker-compose.yml

```yaml
version: "3"
services:
  jupyter:
    build: .
    container_name: "jupyter"
    ports:
      - 8888:8888
    tty: true
    environment:
      - JUPYTER_ENABLE_LAB=yes
    volumes:
      - C:\work\Python:/home/jovyan/work
    command: start-notebook.sh --NotebookApp.token=''
```

# 起動

`docker-compose.yml`, `Dockerfile`の同階層に移動し以下を実行。
起動後、`localhost:8888`にアクセスで使用できる。

```shell
docker-compose up -d
```

# 参考
[オレオレJupyterlab環境をDockerで作った](https://zenn.dev/fuchami/articles/d1625ac784fe5d)
【AWS初心者向け】AWSのbillingでEC2のEBSを使っていないのに請求が来ていた件

#ターゲット
![スクリーンショット 2021-05-30 午後2.24.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/d1ef22e3-3efc-f1d1-25b1-e48784bb8bd4.png)
このようにEBSから請求が来ていて、請求を止めたい。
しかしEBSを使った記憶もないし、そもそも全く動いてない。。。
という人向け

#確認してみる
![スクリーンショット 2021-05-30 午後2.31.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/7edfbafd-3c20-ccf2-d2dc-f802e9279561.png)
念のためインスタンスを確認してみるとterminated(終了)している

![スクリーンショット 2021-05-30 午後2.32.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/9fe29934-52e6-a0b6-3d64-ab1878768ada.png)
EBSのボリュームを確認してみるが使われていない。なぜなら使っていないからだ
![スクリーンショット 2021-05-30 午後2.32.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/0c54d375-352f-c91d-c14a-2556cb36188f.png)
EBSのスナップショットも確認してみる。もちろんん使っていない。

#結論は？
EC2インスタンスをいくつも作成したため、Amazon EBS汎用SSD(gp2)を月に30GB以上利用したため。

インスタンスはこの事象が起きた際に最初に止めたのだが、単純にインスタンスを立てすぎたため請求されたようで、EBSは実は関係ないということだった。。。。

使わないインスタンスは止めよう。
macos神器osascript


### osascript 是什么

`man osascript`

osascript -- execute OSA scripts (AppleScript, JavaScript, etc.)

### 常用

```
osascript -e 'return "hello"'

osascript -e 'get the clipboard'


```

### 显示通知

```
osascript -e ' display notification "通知内容" with title "标题" subtitle "子标题" '

osascript -e 'tell Application "Finder" to display dialog "Job finished" '
```

### 显示系统信息

```
osascript -e "system info"

osascript -e "IPv4 address of (system info)"

osascript -e "CPU type of (system info)"
# Intel x86-64h Haswell
```

### 其他

```
osascript -e "set volume 0"

osascript -e "beep 2"

osascript -e 'display dialog "Did you know that you are annoying?" buttons "Yes" with icon note'

osascript -e  'delay 0.5 '

```

---

参考：

https://sspai.com/post/43758
https://sspai.com/post/46912
https://www.jianshu.com/p/d42dff738d70
https://segmentfault.com/a/1190000011273388
https://github.com/linjunpop/imessage/blob/c026cd9011b3b5ba99687c3dcf13957da6137bac/lib/imessage/sender.rb#L51
https://apple.stackexchange.com/questions/103621/run-applescript-from-bash-script

https://qiita.com/satosystems/items/8fff5b2313ecd6f81af3
https://shuzo-kino.hateblo.jp/entry/2015/01/03/234722
http://www.asahi-net.or.jp/~va5n-okmt/factory/applescript/sample_code/
「オブジェクト指向」の定義と効果についてまとめてみた！

# 目次
- はじめに
- オブジェクト指向の定義
- オブジェクト指向のメリット
- オブジェクト指向の全体像と本質
- まとめ


# はじめに
プログラミングの勉強をしていると、**「オブジェクト指向」** っていう言葉をよく目にしますよね。


自分も最初は「ん、？オブジェクト指向？何それ美味しいの？？」みたいな感じでしたw



オブジェクト指向を初めて学ぶ人が最初にぶつかる壁こそが「オブジェクト指向とは何か？」という事に対して明確な答えが得られない事です。

それぞれ答えが異なり、曖昧でわかりにくい説明をされる事も多いと思います。オブジェクト指向に初めて向き合う人にとって、小難しい学問的なことよりも次のようなシンプルな定義が分かりやすいと思います。



# オブジェクト指向の定義
シンプルにまとめると次のようになります。

###### オブジェクト指向とは、『ソフトウェア開発をするときに用いる部品化の考え方』のこと。


ん？部品化？？

そうなんです。この部品化の考え方にそって、１つのプログラムを複数に部品化すると、その内容が把握しやすくなり、僕たち人間の頭が追いつかない状況を避けることができるのです！

# オブジェクト指向のメリット
オブジェクト指向を用いる根底にある目的は前述した通り、「人間が内容を把握しやすいプログラム開発を実現する」というものです。

オブジェクト指向の考え方を用いて賢い部品化を行うと以下のようなメリットを得る事ができます。



- プログラムの変更が容易になる（柔軟性・保守性の向上）
- プログラムの一部を簡単に転用できる（再利用性の向上）



ただ、これらのメリットは実際の開発業務を経験していく中で、幾度となくコードの修正を行うことによって初めて体感できるメリットだそうです。

なので初めのうちは以下のメリットさえ抑えておけば十分かと思います。


* **ラクして、楽しく、良いものを作れる！**


これにより、創造性を膨らませて色々な機能を実装することに開発者は集中できて、それ以外の仕組みの部分ではオブジェクト指向の考え方のレールに乗っかり、効率よくサービスを作っていけるような気遣いであると捉えるのが良いですね。

# オブジェクト指向の全体像と本質
僕たちがこれから開発していくプログラムやシステムはざっくり言うと、「現実世界における何らかの活動を自動化して効率よくする為のもの」です。

わかりやすく言うと、「僕たち人間がこれまで行ってきたことを機械にやらせて、僕たち人間がラクをする為のもの」と、言い換える事もできますね。


オブジェクト指向の部品化の考えを用いることで、「コードの変更箇所を局所的にする事ができ、対応する部品（クラス）を修正、交換すれば簡単にプログラムを修正することができます。




# まとめ

- オブジェクト指向とは、ソフトウェアを開発する際に用いる部品化の考え方の事。
- オブジェクト指向を用いると、大規模で複雑なソフトウェアであっても、ラクして、楽しく、良いものを開発する事ができる。



参考文献：スッキリわかるJava入門第３版
PMBOKまとめ

#PMBOKの基本
PMBOK＝Project Management Body Of Knowledge

##組織のプロセス資産
・ベンダーのリスト
・計画書などのテンプレート
・品質管理方針
・課題が発生した場合の対処法
・資源の管理方法
・課題管理表などのテンプレート
・標準化された作業の進め方
・労働時間のデータ
・構成管理手順データ
・過去のプロジェクトで得られた教訓

#10の知識エリア
##1.プロジェクト統合マネジメント
プロジェクトやフェーズの進め方・管理や終結の方法について定義
他の知識エリアを取りまとめる役割

■プロセス
①プロジェクト憲章の作成
②プロジェクトマネジメント計画書の作成
③プロジェクト作業の指揮・マネジメントのプロセス
④プロジェクト知識のマネジメント
⑤プロジェクト作業の監視・コントロール
⑥統合変更管理
⑦プロジェクトやフェーズの終結

##2.プロジェクトスコープマネジメント
プロジェクトやフェーズ内で、どのような作業を行い、どのような成果物を生成するかを定義

■プロセス
①スコープマネジメントの計画
②要求事項の収集
③スコープの定義
④WBSの作成
　プロジェクトの成果物や作業を細かくわかりやすい階層構造で表現
⑤スコープの妥当性確認
⑥スコープのコントロール

##3.プロジェクトスケジュールマネジメント
納期管理に関する定義

■プロセス
①スケジュールマネジメントの計画
②アクティビティの定義
　WBSの最小構成要素であるワークパッケージをもとにタスクを定義
③アクティビティの順序設定
④アクティビティの所要時間見積
⑤スケジュールの作成
⑥スケジュールのコントロール

##4.プロジェクトコストマネジメント
事前承認を受けた財源の範囲内で、プロジェクトで利用する予算を設定し、管理する

■プロセス
①コストマネジメントの形アック
②コストの見積もり
③予算の設定
④コストのコントロール

##5.プロジェクト品質マネジメント
生成される成果物やプロジェクトの品質に関する知識

■プロセス
①品質マネジメントの計画
②品質マネジメントのプロセス
③品質のコントロール

##6.プロジェクト資源マネジメント
##7.プロジェクトコミュニケーションマネジメント
「プロジェクトとステークホルダーのニーズが、資料の作成と、会議を通して効果的に情報伝達されるプロセス」

・会議予定を設定
・会議予定に合わせて情報交換する
・必要な情報が適切な人に伝達されている
（狭義のコミュニケーション）

■プロセス
①コミュニケーションマネジメントの計画
　どのような情報を欲しているのか特定
　インプット：ステークホルダー登録簿
　ツールと技法：
　　コミュニケーション要求事項分析（情報ニーズを明確）→各ステークホルダーの立場や環境を分析して情報のニーズを明確にする
　　コミュニケーション技術、モデル、方法（取り組みを明確）→根本的なコミュニケーションロスを軽減
　アウトプット：コミュニケーションマネジメント計画
②コミュニケーションのマネジメント
③コミュニケーションの監視
　適切なやりとりがなされているか監視

##8.プロジェクトリスクマネジメント
##9.プロジェクト調達マネジメント
##10.プロジェクトステークホルダーマネジメント
「ステークホルダーの期待を分析し、ステークホルダーがプロジェクトに影響を及ぼす程度、またはプロジェクトから異教を受ける程度を評価し、プロジェクトの決定およびプロジェクトの計画と実行を支援するために、ステークホルダーからの関与を効果的に引き出すための戦略を作成する」

関与：各ステークホルダーがプロジェクトに対してどの程度関わろうとしているのかを表す意欲
（関与度の5段階：不認識、抵抗、中立、支援型、指導

■プロセス
①ステークホルダーの特定
②ステークホルダーエンゲージメントの計画
③ステークホルダーエンゲージメントのマネジメント
④ステークホルダーエンゲージメントの監視
　計画地と実績値の差異の原因を追究
Elasticsearch 批量导入数据

#### 本人的 Elasticsearch 版本是 6.2.3

#### python script

```python
from datetime import datetime
from elasticsearch import Elasticsearch
from elasticsearch import helpers

es = Elasticsearch()
#es = Elasticsearch("http://localhost:9200/)
#es = Elasticsearch("http://localhost:9200/test/one")

actions = [
  {
    "_index": "test",
    "_type": "one",
    "_id": j,
    "_source": {
        "any":"data" + str(j),
        "timestamp": datetime.now()}
  }
  for j in range(0, 10)
]

helpers.bulk(es, actions)
```
---

参考:

https://stackoverflow.com/questions/20288770/how-to-use-bulk-api-to-store-the-keywords-in-es-by-using-python

https://github.com/elastic/elasticsearch-py
Elasticsearch  安装IK中文分词器并设置索引

#### 本人的 Elasticsearch 版本是 6.2.3

#### 下载并安装插件
```
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.2.3/elasticsearch-analysis-ik-6.2.3.zip
# sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install http://localhost:8000/elasticsearch-analysis-ik-6.2.3.zip -v
```

插件安装在 `/usr/share/elasticsearch/plugins/`
插件的配置文件在 `/etc/elasticsearch/analysis-ik`
测试下 `sudo ./bin/elasticsearch-plugin list`

**注意文件的权限**

### 当然也可以自己编译

#### 安装java Maven
[Maven](https://maven.apache.org/)  是一个项目管理和构建自动化工具, 类似 python的pipenv, nodejs的npm

`sudo apt-get install maven`

#### 编译 elasticsearch-ik

```
https://github.com/medcl/elasticsearch-analysis-ik.git
git checkout v6.2.3
mvn package
```

#### 重启 elasticsearch

`service elasticsearch restart`

#### 设置中文索引
```
curl -X PUT http://localhost:9200/weibo #新建一个index

curl -XPUT http://localhost:9200/weibo/_mapping/news -H 'Content-Type: application/json' -d'
{
  "properties": {
    "summary": {
      "type": "text",
      "analyzer": "ik_smart"
    },
    "title": {
      "type": "text",
      "analyzer": "ik_smart"
    }
  }
}'
```

> ik_max_word: 会将文本做最细粒度的拆分,比如会将 "中华人民共和国国歌"拆分为
"中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌"，会穷尽各种可能的组合
ik_smart: 会做最粗粒度的拆分, 比如会将 "中华人民共和国国歌"拆分为 "中华人民共和国,国歌" .

---

参考:

https://stackoverflow.com/questions/15630055/how-to-install-maven-3-on-ubuntu-17-04-16-10-16-04-lts-15-10-15-04-14-10-14-04-l
https://github.com/medcl/elasticsearch-analysis-ik
http://www.cnblogs.com/xing901022/p/5910139.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-put-mapping.html
http://www.cnblogs.com/softidea/p/6081326.html
在ubuntu上安装elasticsearch

**Elasticsearch版本是 6.2.3**

#### what is elasticsearch

elasticsearch简称es
>Elasticsearch 是一个分布式的 RESTful 风格的搜索和数据分析引擎，能够解决不断涌现出的各种用例。
作为 Elastic Stack 的核心，它集中存储您的数据，帮助您发现意料之中以及意料之外的情况。

#### 安装

首先安装java
`sudo apt-get install openjdk-8-jdk`

下载 [es-deb](https://www.elastic.co/downloads/elasticsearch)
安装 `sudo dpkg -i elasticsearch-6.2.3.deb`
程序位置 `/usr/share/elasticsearch/`
配置文件 `/etc/elasticsearch/elasticsearch.yml`

#### 启动es

二选其一

`service elasticsearch start`

`/usr/share/elasticsearch/bin/elasticsearch -d` 作为一个守护进程在后台运行

是否运行

```
curl http://localhost:9200/

{
  "name": "n93oTbA",
  "cluster_name": "elasticsearch",
  "cluster_uuid": "PccwXXJx0d4C21ZQvDw",
  "version": {
    "number": "6.2.3",
    "build_hash": "cd9ff00",
    "build_date": "2018-03-13T10:06:29.741383Z",
    "build_snapshot": false,
    "lucene_version": "7.2.1",
    "minimum_wire_compatibility_version": "5.6.0",
    "minimum_index_compatibility_version": "5.0.0"
  },
  "tagline": "You Know, for Search"
}
```

##### 停止es

```
cat /var/run/elasticsearch/elasticsearch.pid  && echo # 获得pid

sudo kill -SIGTERM 15516
```

#### Kibana
> Kibana 让您能够可视化es中的数据并操作es
![kibana.jpg](https://upload-images.jianshu.io/upload_images/47789-a6df3fc24d75d190.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

下载[kibana-deb](https://www.elastic.co/cn/downloads/kibana)
安装 `sudo dpkg -i kibana-6.2.4-amd64.deb`
位置 `/usr/share/kibana/`
启动 `/usr/share/kibana/bin/kibana`
访问 `http://localhost:5601`

#### 手动安装Kibana

手动安装方便自定义配置

```
git clone https://github.com/elastic/kibana.git
cd kibana
git checkout v6.2.3 #es是6.2.3，kibana就切换到 v6.2.3
```

去掉Kibana对nodejs版本的限制
为啥 听人劝 吃饱饭

```diff
#package.json文件

   "engines": {
-    "node": "6.12.2",
     "yarn": "^1.3.2"
   }
 }
```

安装yarn `npm install -g yarn`
安装kibana的依赖 `yarn kbn bootstrap`
启动kibana `yarn start`

修改配置文件

```diff
# config/kibana.yml

-server.host: "localhost"
+server.host: "192.168.1.2"

-elasticsearch.url: "http://localhost:9200"
+elasticsearch.url: "http://192.168.1.1:9200/"
```

#### Kibana console

>![Sense.png](https://upload-images.jianshu.io/upload_images/47789-800923b0904d0a6a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

请求 es api `http://localhost:5601/app/kibana#/dev_tools/console?_g=()`

---

参考:

https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#setting-up-your-development-environment
在ubuntu上安装docker

> ![solomon good bye](https://upload-images.jianshu.io/upload_images/47789-2b62a3153200ddca.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

### what is Dokcker

> [Docker](https://www.docker.com/) 是一个开源的应用容器引擎，它让开发者可以打包他们的应用以及依赖包到一个可移植的容器中，然后发布到安装了任何 Linux 发行版本的机器上。Docker基于LXC来实现类似VM的功能，可以在更有限的硬件资源上提供给用户更多的计算资源。与其他VM等虚拟化的方式不同，LXC不属于全虚拟化、部分虚拟化或半虚拟化，而是一个操作系统级虚拟化。
Docker最初实现是基于 LXC，从 0.7 版本以后开始去除 LXC，转而使用自行开发的 libcontainer，从 1.11 开始，则进一步演进为使用 runC 和 containerd。


### 为什么使用 Docker

1. 更高效的利用系统资源
2. 更快速的启动时间
3. 一致的运行环境
4. 持续交付和部署
5. 更轻松的迁移
6. 更轻松的维护和扩展


对比传统虚拟机

| 特性 | Docker | 传统虚拟机 |
| ------| ------ | ------ |
| 启动 | 秒级 | 分钟级 |
| 硬盘使用 | 一般为MB | 一般为GB |
| 性能 | 接近原生 | 弱于 |
| 系统支持量 | 单机支持上千个 | 一般几十个 |


### 安装

先删除 `sudo apt-get remove docker docker-engine docker.io`

安装中科大的源 大陆安装速度快

```shell
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

sudo add-apt-repository \
    "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
    $(lsb_release -cs) \
    stable"

sudo apt-get update

sudo apt-get install docker-ce
```

也可安装官方源

```shell
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

sudo apt-get update

sudo apt-get install docker-ce
```

如果提示  `docker-ce Depends: libseccomp2 (>= 2.3.0) but 2.2.3-3ubuntu3 is to be installed`

```
apt-cache madison docker-ce
sudo apt install docker-ce=17.06.0~ce-0~ubuntu
```

### 运行

```
sudo systemctl enable docker
sudo systemctl start docker
```

也可
`sudo /usr/bin/dockerd -s aufs -p /var/run/docker.pid`

---

参考:

https://www.scalyr.com/blog/create-docker-image/
https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04
https://docs.docker.com/install/linux/docker-ce/ubuntu/
https://docs.docker.com/config/daemon/
https://yeasy.gitbooks.io/docker_practice/install/ubuntu.html
https://yeasy.gitbooks.io/docker_practice/install/mirror.html
https://itbilu.com/linux/docker/VyhM5wPuz.html
https://blog.docker.com/2018/03/au-revoir/
PostgreSQL hstore: 保存json结构数据

Postgre支持的数据类型非常丰富, 可以储存 **mac地址 ip地址 path路径 数组** 等类型.
大家可能用到的情况不是很多, 不过有种数据结构你可能会需要 `hash类型`

>![datatype.png](https://upload-images.jianshu.io/upload_images/47789-a68c3eb3b4e3b418.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

hstore 储存的结构类似于MongoDB, 想体验nosql的便利, 可以用用hstore啊

####开启 hstore extension

`CREATE EXTENSION hstore;`

#### 表结构

```
CREATE TABLE books (
 id serial primary key,
 title VARCHAR (255),
 attr hstore
);
```

####插入数据

```sql
INSERT INTO books (title, attr)
VALUES
 (
 'PostgreSQL Tutorial',

  '
    "paperback" => "243",
    "publisher" => "postgresqltutorial.com",
    "language"  => "English",
    "ISBN-13"   => "978-1449370000",
    "weight"    => "11.2 ounces"
  '
);

------

-- "author" => "shooter" 多了个作者

INSERT INTO books (title, attr)
VALUES
(
 'PostgreSQL Cheat Sheet',
 '
  "author" => "shooter",
  "paperback" => "5",
  "publisher" => "postgresqltutorial.com",
  "language"  => "English",
  "ISBN-13"   => "978-1449370001",
  "weight"    => "1 ounces"
 '
);
```

#### 查询

```sql
SELECT attr FROM books; -- 普通查询

SELECT
 attr -> 'weight' AS weight
FROM
 books
WHERE
 attr -> 'ISBN-13' = '978-1449370000';

SELECT
 title
FROM
 books
WHERE
 attr @> '"weight"=>"11.2 ounces"' :: hstore;
```

#### 更新

```
UPDATE books
SET attr = attr || '"freeshipping"=>"yes"' :: hstore;

UPDATE books
SET   attr = '"author"=>"shooter"' :: hstore;
```

#### 删除属性
```
UPDATE books 
SET attr = delete(attr, 'freeshipping');
```
---

hstore 跟json/jsonb的 性能差异，在用了后在说吧

---

参考:
[Use unstructured datatypes Hstore vs JSON vs JSONB](https://www.citusdata.com/blog/2016/07/14/choosing-nosql-hstore-json-jsonb/)

http://chenxiaoyu.org/2013/11/28/postgresql-array/
http://www.postgresqltutorial.com/postgresql-hstore/
https://www.zhihu.com/question/20010554/answer/62628256

https://my.oschina.net/swuly302/blog/143746 2013年翻译的文章 只供参考
Hive

[Hive](https://hive.apache.org/)
>The Apache Hive data warehouse software facilitates reading, writing, and managing large datasets residing in distributed storage using SQL. Structure can be projected onto data already in storage. A command line tool and JDBC driver are provided to connect users to Hive.

####进入hive

```
hive
hive --service cli
hive -S #静默模式 不打印输出信息
```

#### hive命令

```sql
show databases;
use <dbname>; -- 连接数据库
show tables;
show functions; --显示内置函数

desc <tbl>;     -- 显示表结构
dfs -ls <dir>;   -- 在hive里显示hdfs的目录
```
 
```
create table person 
(id int,
name string,
married boolean,
salary double);

desc  person;
------------------------------
create table student 
( id int,
  name string,
  grade array<float>);

------------------------------
create table student
( id int,
  name string,
  grade map<string, float>);
------------------------------
create table student
( id int,
  info struct<name: string, age:int, gender: string>
);
```

#### hive执行shell命令

```
!pwd;
!ls;
! cat /proc/cpuinfo;
```

#### HQL 查询

```
select * from tbl; --不会转换为 MapReduce
select title from tbl; -- 转换为 MapReduce
```
redis 内存

```
info memory #查看总内存使用量

# Memory
used_memory:623473632
used_memory_human:594.59M
used_memory_rss:697462784
used_memory_rss_human:665.15M
used_memory_peak:674267576
used_memory_peak_human:643.03M
used_memory_peak_perc:92.47%
used_memory_overhead:34927114
used_memory_startup:786576
used_memory_dataset:588546518
used_memory_dataset_perc:94.52%
total_system_memory:8229302272
total_system_memory_human:6.66G
...

#####################
MEMORY USAGE "0x9271AB1be3177bF3E3B684a8783698F1B9D600a2"
# => (integer) 116  # key "0x9271AB1be3177bF3E3B684a8783698F1B9D600a2" 的内存使用量

MEMORY USAGE  0x5592b69c8decfbd66a4f346f45cd1b2aa1359393fb40afff7b2c6ecbfebaa6c2
# => (integer) 943

# 获取内存配置
CONFIG GET maxmemory
# 1) "maxmemory"
# 2) "4294967296"

```

#### 淘汰策略

```
CONFIG GET maxmemory-policy
# 1) "maxmemory-policy"
# 2) "volatile-lru"

```

> volatile-lru:从已设置过期时间的内存数据集中挑选最近最少使用的数据淘汰
volatile-ttl: 从已设置过期时间的内存数据集中挑选即将过期的数据 淘汰
volatile-random:从已设置过期时间的内存数据集中任意挑选数据 淘汰
allkeys-lru:从内存数据集中挑选最近最少使用的数据 淘汰
allkeys-random:从数据集中任意挑选数据 淘汰
no-enviction:禁止驱逐数据 (默认淘汰策略). 当redis内存数据达到maxmemory,直接返回OOM错误

---

参考:

https://blog.tanteng.me/2016/03/redis-maxmemory/
https://redis.io/commands/memory-usage
https://redis.io/commands/dbsize
https://redis.io/commands/flushdb
https://redis.io/commands/config-get
https://stackoverflow.com/a/5756201
数学与可视化

### 工具
http://www.jihehuaban.com.cn/ 几何画板
https://www.geogebra.org/
https://www.geogebra.org/geometry
https://www.desmos.com/calculator
http://www.wolfram.com/

### 视频
http://www.3blue1brown.com/
http://www.numberphile.com/

### 做题
https://brilliant.org/
https://projecteuler.net/
https://artofproblemsolving.com/

### 科学计算
https://www.juliabox.com/    julia语言
https://octave-online.net/  gnu matlab 实现
https://matlab.mathworks.com/ 收费的matlab online
http://bigsec.net/b52/scipydoc/index.html python
https://processing.org/ processing
Jupyter Notebook使用技巧

####  Jupyter生成ppt
安装完jupyter，打开后，建立新.ipynb文件。

点击view ------ cell toolbar ------slideshow。此时每个cell右上角会出现slide type，点击下拉，出现5种选项，意思如下：

Slide：主页面，通过按左右方向键进行切换。
Sub-Slide：副页面，通过按上下方向键进行切换。
Fragment：一开始是隐藏的，按空格键或方向键后显示，实现动态效果。
Skip：在幻灯片中不显示的单元。
Notes：作为演讲者的备忘笔记，也不在幻灯片中显

#### Matplotlib 在 Jupyter Notebook 上面输出矢量图

```python
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format = 'svg'
```

#### 只显示markdown和图表
想没有想过一个场景，你的jupyter notebook是导出一个报告给业务人员看的，他们不想看到那些密密麻麻的代码，只想留下markdown和图表，在jupyter notebook加入下面这段代码就好

```python
import IPython.core.display as di

di.display_html('<script><jQuery(function() {if (jQuery("body.notebook_app").length == 0) { jQuery(".input_area").toggle(); jQuery(".prompt").toggle();}});</script>',raw=True)
```

#### Jupyter kernels
Jupyter不但可以运行python，还可以运行很多其他语言， 
比如Ruby Julia Golang R

[Jupyter kernels](https://github.com/jupyter/jupyter/wiki/Jupyter-kernels) 列出了不同语言的 Jupyter kernels

### 2019-04-04

```
%matplotlib inline

jupyter nbconvert *.ipynb --to slides 
jupyter notebook --ip=0.0.0.0 --allow-root
iruby notebook --ip=0.0.0.0 --allow-root
```

https://nbviewer.jupyter.org/github/NervosBeijingCommunity/jupyter-ppt/blob/master/RubySaturday20190309/gen-btc-addr.ipynb

---

参考: 
https://www.jianshu.com/p/7cac2e5ec35b
https://github.com/SciRuby/iruby
https://github.com/dunovank/jupyter-themes
https://www.dataquest.io/blog/advanced-jupyter-notebooks-tutorial/
https://towardsdatascience.com/speed-up-jupyter-notebooks-20716cbe2025
https://zhuanlan.zhihu.com/p/37590039
https://www.zhihu.com/question/59392251/answer/177708041
https://github.com/jupyter/dashboards
https://github.com/damianavila/RISE
内网穿透神器——frp

>![](https://upload-images.jianshu.io/upload_images/47789-d42de1305e8395dd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

[frp](https://github.com/fatedier/frp) 是一个可用于内网穿透的高性能的反向代理应用，支持 tcp、 udp 协议，为 http 和 https 应用协议提供了额外的能力，且尝试性支持了点对点穿透。

如果你之前用过[ngrok](https://ngrok.com/)，一定不会对frp的功能陌生。ngrok 开源版好久没更新了，高级版需要花钱。

### 内网穿透

通俗的讲，我在本地启动了个http服务，只能在局域网访问，怎么能让局域网外的人瞧瞧呢？这就需要内网的服务摆脱限制，穿透到外网去，顾名思义了 “内网穿透”。

### 哲学三问之：有什么用

做过 **微信开发** 么，在验证 **远程服务地址** 的时候，需要频繁的修改，或者远程服务器不能随意修改，有固定的发布日期。

你可以在本地修改，通过内网穿透 映射到到一个远程服务地址， 微信链接到这个远程地址，其实链接的是本地开发环境。等全部功能开发完毕，统一部署到正式的远程服务器上，这方便的很啊。

### 通过自定义域名访问部署于内网的 web 服务

####  下载

https://github.com/fatedier/frp/releases/tag/v0.25.3

#### 服务器端
需要先买好一台vps，部署好环境，ip是 `x.x.x.x`，并在防火墙上开启5555、3000端口。服务器端运行的是 `frp-s`命令。

```
# frps.ini 文件
[common]
bind_port = 5555
vhost_http_port=3000 # 远程服务要映射的端口号
```

运行 `frps -c ./frps.ini`

#### 本地服务

本地端运行的是 `frp-c`命令。

```
# frpc.ini 文件
[common]
server_addr = x.x.x.x
server_port = 5555

[web]
type = http
local_port = 3000 #本地服务3000端口
custom_domains = x.x.x.x 
```

运行  `frpc -c ./frpc.ini`

#### 启动本地服务

确保启动frps，再启动frpc，最后在启动本地的http服务。
好比有个nodejs项目， 使用 `npm start` 启动服务。

#### 过程

本地3000端口的服务，映射到了 x.x.x.x:3000
`localhost:3000 => frpc  => 5555端口 => frps => x.x.x.x:3000`

访问端口可以不一样，本地8000端口的服务，映射到了 x.x.x.x:4000
`localhost:8000 => frpc => 5555端口 => frps => x.x.x.x:4000`

你也可以用不同的端口映射
`localhost:8000 => frpc  => 6666端口 => frps => x.x.x.x:4000`

都可以通过配置文件进行修改

我的博客即将同步至腾讯云+社区，邀请大家一同入驻：https://cloud.tencent.com/developer/support-plan?invite_code=3kh51td0b3ggw

---

参考：
 
http://wjp2013.github.io/tool/frp/
https://github.com/fatedier/frp/blob/master/README_zh.md
https://blog.ilemonrain.com/linux/frp-for-proxyconnect.html
https://www.jianshu.com/p/057e3266f380
https://github.com/cnlh/nps
使用Exiftool 查看图片的GPS

> ![exif](https://upload-images.jianshu.io/upload_images/47789-bc0ee33ecfd5ea21.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

```
exiftool '-Make=shooter' file.png
exiftool '-Software=shooter' file.png
exiftool -Model='Kodak Hawkeye Instamatic' file.jpg

exiftool -a -u -g1  file.png
exiftool -n -gpslatitude -gpslongitude  file.png
exiftool -filename -gpslatitude -gpslongitude -T file.png
```

### 设定个 alias

`alias gps="exiftool -gpslatitude -gpslongitude -gpsaltitude -Make -filename -n -T"`

### 查询

```
locat file.jpg

22.81  107.54 -37.95 HUAWEI #显示的分别是 纬度 经度 海拔 相机制造商
```

### Exiftool 同样能检索视频

```
locat file.mp4

22.81  107.54 56.23 Apple
```

### ffprobe 能得到更为丰富的信息

```
ffprobe -show_streams -i file.mp4
```

### 删除gps信息

`exiftool -gps:all=  file.png` 删除照片所有的gps信息
`exiftool "-gps*=" file.png`   删除照片一部分gps信息

### 删除时间信息

`exiftool -alldates= -gpsdatestamp= -gpstimestamp= file.jpg`
`exiftool -a -s -G1 -time:all file.jpg`

---

参考：

https://zhuanlan.zhihu.com/p/71915158
https://exif.tuchong.com
https://exifinfo.org/
https://www.jianshu.com/p/d76457799de1
https://liangxu.wang/1687
http://blog.knownsec.com/2015/02/a-real-case-study-of-xss-through-exif-headers
javascript: getOwnPropertyNames

`Object.getOwnPropertyNames`是es5中新增的方法，用来获取对象自身的全部属性名。

```
​function getAllMethods(obj) {
  return Object.getOwnPropertyNames(obj).filter(function(property) {
    return typeof obj[property] == 'function';
  });
}

console.info(getAllMethods(Math));
// abs acos acosh asin asinh atan atanh atan2 ceil cbrt expm1 clz32 cos cosh 
// exp floor fround hypot imul log log1p log2 log10 max min pow random round 
// sign sin sqrt tan tanh trunc sinh clamp degrees fscale iaddh isubh imulh 
// radians scale umulh signbit
```

---

参考：
https://yanhaijing.com/javascript/2015/05/08/member-of-object/
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames
https://stackoverflow.com/a/2946616
vscode修改快捷键映射

> ![](https://upload-images.jianshu.io/upload_images/47789-a943b79409787491.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 显示空格的控制字符

```
"editor.renderControlCharacters": true,
"editor.renderWhitespace": "all"
```
## 保存时自动删除行尾多余空格

`  "files.trimTrailingWhitespace": true`

## mac系统切换table的快捷键

>![keymaps](https://upload-images.jianshu.io/upload_images/47789-1a59cc609517d855.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

```
//~/Library/Application Support/Code/User/keybindings.json
//~/Library/Application Support/Code - Insiders/User/keybindings.json

[
    {
        "key": "cmd+0",
        "command": "workbench.action.openLastEditorInGroup"
    },
    {
        "key": "cmd+1",
        "command": "workbench.action.openEditorAtIndex1"
    },
    {
        "key": "cmd+2",
        "command": "workbench.action.openEditorAtIndex2"
    },
    {
        "key": "cmd+3",
        "command": "workbench.action.openEditorAtIndex3"
    },
    {
        "key": "cmd+4",
        "command": "workbench.action.openEditorAtIndex4"
    },
    {
        "key": "cmd+5",
        "command": "workbench.action.openEditorAtIndex5"
    },
    {
        "key": "cmd+6",
        "command": "workbench.action.openEditorAtIndex6"
    },
    {
        "key": "cmd+7",
        "command": "workbench.action.openEditorAtIndex7"
    },
    {
        "key": "cmd+8",
        "command": "workbench.action.openEditorAtIndex8"
    },
    {
        "key": "cmd+9",
        "command": "workbench.action.openEditorAtIndex9"
    },
    {
        "key": "ctrl+1",
        "command": "workbench.action.focusFirstEditorGroup"
    },
    {
        "key": "ctrl+2",
        "command": "workbench.action.focusSecondEditorGroup"
    },
    {
        "key": "ctrl+3",
        "command": "workbench.action.focusThirdEditorGroup"
    }
]

```

---

参考：

https://stackoverflow.com/a/46087295
https://www.latelee.org/pkc/vs-code-usage.html
https://www.jianshu.com/p/feb23a8d8cdb
Unity  AwakeとStartとOnEnableの呼ばれる順番 

##0.0 はじめに
Awake() OnEnable() Start()が実行される順番を調べてみた。



##1.0 呼び出される順番
Awake() → OnEnable() → Start()



##1.1 Awake()
シーンが始まるとすぐに呼び出されます（スクリプトのインスタンスがロードされたとき）。なのでStartより先に呼ばれます。参照先のAwakeの処理が終わってない可能性がある為、参照からの値の取得は注意が必要です。オブジェクトが有効でないと呼ばれません。また1回だけしか呼び出されません。



##1.2 Start()
最初のフレームにて呼び出される。Updateの1フレーム前で呼ばれます。
オブジェクトが有効でないと呼ばれません。また1回だけしか呼び出されません。



##1.3 OnEnable()
名前の通りブジェクトがSetActive(true)などで有効(アクティブ)になったときに呼び出されます。
他とことなり何回でも呼ばれます。（もう一度オブジェクトがアクティブになったときにも呼ばれます）
Awakeより後、Startより先に呼ばれます。

ちなみに非アクティブになった時に呼ばれる関数はOnDisable()です。こちらはゲームスタート時（最初に再生した時）に非アクティブでも呼ばれないので注意が必要です。
通过shell判断操作系统发行版

```
if [[ "$OSTYPE" == "linux-gnu" ]]; then
	if [ -f /etc/redhat-release ]; then
		echo "Redhat Linux detected."
	elif [ -f /etc/SuSE-release ]; then
		echo "Suse Linux detected."
	elif [ -f /etc/arch-release ]; then
		echo "Arch Linux detected."
	elif [ -f /etc/mandrake-release ]; then
		echo "Mandrake Linux detected."
	elif [ -f /etc/debian_version ]; then
		echo "Ubuntu/Debian Linux detected."
	else
		echo "Unknown Linux distribution."
	fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
	echo "Mac OS (Darwin) detected."
elif [[ "$OSTYPE" == "freebsd"* ]]; then
	echo "FreeBSD detected."
else
	echo "Unknown operating system."
fi
```

https://getsubstrate.io
Fping - Linux的高性能Ping工具

>![](https://upload-images.jianshu.io/upload_images/47789-02e9a7b067e25f55.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

fping是一个主机扫描工具，相比于ping工具可以批量扫描主机。

### 常用参数

```
-a：只显示存活主机
-u：只显示不存活主机
-l：循环ping
```

### 例子

```
fping ip1 ip2 ip3 ...
fping -f filename
fping -g ip1 ip2 (ip1地址开始范围，ip2地址结束范围)
```

---

参考：
https://www.cnblogs.com/ym123/p/4549579.html
https://www.howtoing.com/ping-multiple-linux-hosts-using-fping
Mosh: 一款替代SSH的远程登录软件

>![](https://upload-images.jianshu.io/upload_images/47789-02e9a7b067e25f55.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

### Mosh是什么

[Mosh](https://mosh.org/)表示移动Shell(Mobile Shell)，可以说是 SSH 的 mobile 版本。
**Mosh最大的特点是基于UDP方式传输**，支持在服务端创建一个临时的Key供客户端一次性连接，退出后失效；也支持通过SSH的配置进行认证，但数据传输本身还是自身的UDP方式。

### SSH的问题

SSH 作为一个远程访问协议，在提出时是为了解决 telnet 的安全性。在 20 多年后(SSH 在 1995 年由 Tatu Ylönen 提出)，它已经成为了远程shell 访问的事实标准。

SSH 采用了 TCP， TCP 在 SSH 设计之初是最好的选择。TCP 提供的特性(面向连接、可靠)简直就像量身定制。但是在现在，这种面向连接的设计却不够灵活了：TCP 的有状态连接使得设备在切换网络，或连接因其他原因断开的时候，就会丢失整个 session 无法恢复。

### Mosh 要解决什么问题

- 解决漫游时连接中断问题。当然不仅仅是漫游的问题，还有电脑休眠、无线网闪断等情况。以前的方式是使用 screen 或 tmux。

- 解决了回显慢的问题。这一点尤为重要。一般的 term 所有输入和输出都需要与远程服务器交互，甚至每次敲击键盘的回显也是由远端的 shell 进程控制。mosh 客户端使用代理，对大部分可以预测的回显，直接在本地完成。这一改进意味着以后登陆一个网络很大的服务器，输入命令时不再等待每个字符回显，而可以一口气写下来，由 mosh 去同步命令。

- ......

### 使用

服务端：

```cpp
mosh-server -p 3000 #启动 3000 端口

#MOSH CONNECT 3000 PoLSHfJxwzQ7EcxgdIcmvA
```

客户端：

```cpp
MOSH_KEY=PoLSHfJxwzQ7EcxgdIcmvA mosh-client 1.1.1.1 3000
```

---

参考：

https://zhuanlan.zhihu.com/p/28414523
https://www.hi-linux.com/posts/23118.html
https://blog.yangl1996.com/post/mosh-the-ssh-replacement/
https://my.oschina.net/hao7234/blog/358217
https://github.com/mobile-shell/mosh/issues/1039
2Dゲーム制作でマウスの方向にキャラクターを向かせたい

## 1,Unityの2Dでキャラクターの正面をマウスの方向に向けるには？
まず必要なのはキャラクターの位置とマウスの位置、キャラクターの位置はオブジェクトクラスから取って取れますせす、次にマウスの位置を取るには

```
Input.mousePosition;
```

これでまずマウスの位置を取れましたが、これは**スクリーン座標**ですので**ワールド座標**に変換してあげないと使えませんそうするために、そうするためにカメラクラスを持って来てScreenToWorldPoint関数を使ってワールド座標にします。

```
Vector2 mousePos; camera.ScreenToWorldPoint(Input.mousePosition);
```

ワールド座標のマウスが取れました、これでキャラクターの位置とマウスの位置が揃いました
次に二つの位置の距離を取ります

```
Vector2 lookDir = mousePos - Character.position;
```

そしてこれでどうやってやるのかというと、Matf.Atan2という関数で距離を使って角度を求められます。

```
float angle = Mathf.Atan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg - 90f;
```

これでマウスの方向にキャラクターの正面を向くように出来ました！
簡単に説明するとMathf.Atan2でラジアンが変えてくるのでMathf.Rad2Degをかけて度に変えます、そして
-90度を引いてやって正面を向かせます。
これでマウスの方向にキャラクターを向かせることができました。
android adb

>![](https://upload-images.jianshu.io/upload_images/47789-155ef8aaa41db25f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

### ADB是什么

ADB，即 [Android Debug Bridge](https://developer.android.com/studio/command-line/adb.html) 是一种允许模拟器或已连接的 Android 设备进行通信的命令行工具，它可为各种设备操作提供便利，如安装和调试应用，并提供对 `Unix shell`（可用来在模拟器或连接的设备上运行各种命令）的访问。可以在`Android SDK/platform-tools`中找到 `adb` 工具或下载 [ADB Kits]( http://adbshell.com/downloads) 。

### 查看adb的版本信息

`adb version`

### 显示设备列表

```
adb devices

List of devices attached
LK7N18125001132	device
```

### 关闭usb调试

`adb shell settings put global adb_enabled 0`

### 打开usb调试

`adb shell settings put global adb_enabled 1`

### 查询usb调试开关情况

`adb shell settings get global adb_enabled`

### 打开模拟定位

`adb shell settings put secure  mock_location 1 `

### 打开坐标

`adb shell settings put system pointer_location 1 `

### 模拟home按键

`adb shell input keyevent 3`

### 模拟按下 Power 键

`adb shell input keyevent 26`

### 模拟 touch屏幕事件

点击屏幕(x, y) = (350, 350)位置

`adb shell input tap 350 350`

### 模拟滑动的事件

从屏幕(150, 150) 滑到屏幕(300, 300)

`adb shell input swipe 150 150 300 300`

### 输入文字

`adb shell input text 123`

### 查看 WiFi IP 地址

```
adb shell ip -f inet addr show wlan0

<BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 3000
    inet 192.168.0.100/24 brd 192.168.0.255 scope global wlan0
       valid_lft forever preferred_lft forever

```

### 开启adb服务

默认启动 `5037` 端口

```
adb start-server

netstat -na | grep 5037

tcp4       0      0  127.0.0.1.5037         127.0.0.1.65208        ESTABLISHED
tcp4       0      0  127.0.0.1.65208        127.0.0.1.5037         ESTABLISHED
tcp4       0      0  127.0.0.1.5037         127.0.0.1.65206        ESTABLISHED
tcp4       0      0  127.0.0.1.65206        127.0.0.1.5037         ESTABLISHED
tcp4       0      0  127.0.0.1.5037         127.0.0.1.65204        ESTABLISHED
tcp4       0      0  127.0.0.1.65204        127.0.0.1.5037         ESTABLISHED
tcp4       0      0  127.0.0.1.5037         127.0.0.1.65202        ESTABLISHED
tcp4       0      0  127.0.0.1.65202        127.0.0.1.5037         ESTABLISHED
tcp4       0      0  127.0.0.1.5037         *.*                    LISTEN
```

### 查看系统应用

`adb shell pm list packages -s`

### 查看第三方应用

`adb shell pm list packages -3`

### 查看应用安装路径

`adb shell pm path <package-name>`


###  通过 TCP 连接设备

```shell
adb tcpip 5555
adb connect 192.168.1.3:5555

adb devices
```

### 关闭 adb服务

```
adb kill-server
```

---

参考：

https://juejin.im/post/5b5683bcf265da0f9b4dea96

https://developer.android.com/studio/command-line/adb?hl=zh-Cn

https://cwgoover.github.io/2016/05/31/android-setting-pointer-location/

https://android.stackexchange.com/a/114081

https://segmentfault.com/a/1190000015345637

https://github.com/esauvisky/PGo-CalcaBotaBotaCalca
git 的一些特殊用法

>![](https://upload-images.jianshu.io/upload_images/47789-5ed116b5f073c234.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 同步github PR到本地

比如同步bitcoin的第11000个PR  https://github.com/bitcoin/bitcoin/pull/11000
在项目目录下执行`git fetch origin  pull/11000/head:pr_11000`

通用格式：`git fetch <remote>  pull/11000/head:<branch_name>`


## GitHub开启二次验证后, 无法通过https的方式clone项目

>![](https://upload-images.jianshu.io/upload_images/47789-bd3fe9258199af62.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

GitHub [开启二次验证后](https://github.com/settings/two_factor_authentication/intro)， 无法通过 https 的方式clone项目

申请 [Personal access tokens](https://github.com/settings/tokens)，申请的token 当做用户密码，就能正常clone项目。


## Github绑定GPG签名

https://qiita.com/shooter/items/3a2c7a972db2488f4b3f

## clone 单独的branch

`git clone <repo_url> --branch <tag_name> --single-branch`

`git clone --branch gh-pages https://github.com/Semantic-Org/Semantic-UI-Docs docs-gh-pages --single-branch  ` 克隆 Semantic-UI-Docs 的 gh-pages 分支到 本地的docs-gh-pages 文件夹

## 获得两个版本间所有变更的文件列表

```
git diff  --name-status 052eaed16a <tag_name>

git diff 052eaed16a <tag_name> --stat
```

>![](https://upload-images.jianshu.io/upload_images/47789-5ff716033810d1a8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## submodule

Git Submodule 允许一个git仓库，作为另一个git仓库的子目录，并且保持父项目和子项目相互独立。

```
git submodules

git submodule update --init # clone 后自动初始化子项目

git submodule update --remote
```
## git clean

**FBI warning:** `git clean -df` 之后的文件无法恢复

`git clean -n`
是一次clean的演示， 告诉你哪些文件会被删除。 这个命令不会真正的删除文件，只是一个提醒。

`git clean -f`
删除当前目录下所有没有track过的文件。不会删除 `.gitignore`文件里指定的文件夹和文件，不管这些文件有没有被track过。

`git clean -f <path>`
删除指定路径下的没有被track过的文件

`git clean -df`
删除当前目录下没有被track过的文件和文件夹

`git clean -xf`
删除当前目录下所有没有track过的文件。不管是不是`.gitignore`文件里面指定的文件夹和文件。

---

参考：

https://stackoverflow.com/questions/1911109/how-do-i-clone-a-specific-git-branch
https://tecadmin.net/clone-specific-git-branch
https://segmentfault.com/q/1010000000133613
https://www.jianshu.com/p/f8a55b972972
https://stackoverflow.com/a/34919582/6132577
https://help.github.com/articles/checking-out-pull-requests-locally/
https://stackoverflow.com/a/34919582/6132577
http://www.cnblogs.com/irocker/p/git-clean.html
https://loveky.github.io/2013/12/18/git-clean/
从docx文件中提取纯文本

>![](https://upload-images.jianshu.io/upload_images/47789-bd8728a2aa333e15.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 解压`docx`文件

直接使用`unzip file.docs` 命令，解压出来很多文件

```
├── [Content_Types].xml
├── _rels
├── docProps
│   ├── app.xml
│   └── core.xml
└── word
    ├── _rels
    │   └── document.xml.rels
    ├── document.xml
    └── settings.xml
```

查看下 `word/document.xml`的内容，非常标准的xml格式的文件

>![](https://upload-images.jianshu.io/upload_images/47789-def872cc48c53eb0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 提取 xml中的纯文本

```
cat word/document.xml sed -e 's/<[^>]\{1,\}>//g; s/[^[:print:]]\{1,\}//g'
```

组合命如下， `unzip -p`  是解压文件到管道流，而不是输出文件。

```
unzip -p file.docx word/document.xml | sed -e 's/<[^>]\{1,\}>//g; s/[^[:print:]]\{1,\}//g'
```
---

参考：

https://www.commandlinefu.com/commands/view/4311/extract-plain-text-from-ms-word-docx-files
忽略Mac系统的版本升级

>![](https://upload-images.jianshu.io/upload_images/47789-5772f5a56d291f81.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

```
sudo softwareupdate  --ignore "macOS Catalina"
defaults write com.apple.systempreferences AttentionPrefBundleIDs 0
killall Dock
```

如果你以后想更新到macOS Catalina，只需在终端里输入以下命令：

`sudo softwareupdate --reset-ignored`

---

`sudo spctl --master-disable`
[Install-Software-from-Unsigned-Developers-on-a-Mac](https://www.wikihow.com/Install-Software-from-Unsigned-Developers-on-a-Mac)

---

参考：

https://mp.weixin.qq.com/s/qqGq4nkMJzmRG5-nmtfx_w