OmniAICreator/Qiita-1.07M huggingface dataset:
仕事術について

仕事術についてコツやアドバイスなどを少し書いてみます。
いろいろと異論はあるとは思いますが、自分が仕事をするうえで大切にしていることなのでご参考程度でお願いします。

###仕事の進め方（プロセス）ついて
仕事を進めるにあたりプロセスに関しては以下の流れになるかと思います。
```　仕事の内容理解（把握）　→　準備　→　実行　→　反省と振り返り　```

■仕事の目的や要件の理解（全体像の把握） 
　　与えられた仕事の目的やゴール（納期）、全体の流れを仕事に取りかかる前に
　　しっかり把握しましょう。不明なところはどんどん依頼者に確認します。
　　確認しすぎるくらいが丁度いい思います。
■仕事の準備をする
　　具体的な仕事の準備にとりかかりましょう。特に仕事の期限を意識し、おおまかな
　　内容をイメージしましょう（場合によってはスケジュールを書き起こしましょう）
　　またスケジュール感に問題ないか依頼者に確認しましょう。
■仕事を実行する
　　仕事を実行する際には、準備段階では想像できなかった様々なこと起こります。
　　自身で解決が難しい場合は依頼者や周りの先輩に適時相談して進めていきましょう。
　　その際にどこまで進めていてどこで行き詰っているのか具体的に第三者に分かりやすく
　　説明することが大事です。
■実行した仕事について反省や振り返りをする
　　仕事が完了し依頼者に報告したら今回行った仕事に対する反省点などを簡単に
　　まとめましょう。もしかしたら工夫すれば、その仕事は想定より円滑に
　　進んだかもしれません。新人の頃はは仕事を通して経験を積むことも大切な
　　要素だと思います。実行した仕事については、しっかり振り返りや反省を行い
　　次回に備えましょう。


##仕事をするうえで大事にしたほうがよいと思うこと
###コミュニケーションを大切にする
コミニュケーションとは、気持・意見などを、言葉などを通じて相手に伝えることです。コミュニケーションで重要なことはお互いの話を聴きお互いに理解することが重要かと思います。また仕事は一人で完結するものではなく、必ず他の人とのつながりの中で進んでゆくものです。日頃からコミュニケーションを上手く取っていると、気軽に周りの人に仕事の相談や依頼などができたり、困っている際も助けてもらえる場合もあります。そのため、仕事の効率をアップさせるには、日頃のコミュニケーションがとても大切です。
 
###報連相をしっかり行う
報連相とは、報告・連絡・相談の頭を取った略語で、ビジネスにおけるコミュニケーションの基本で仕事をスムーズに進めるために必要なものです。「報告」とは上司（仕事の依頼者）からの指示・命令・依頼に対して、状況報告・結果を共有することです。「連絡」とは情報を伝えれること。大事なことは、事実のみを関係者全員を周知することです。「相談」とは、物事を決定する際に他の人に意見を求めたり、話し合いをすることです。上司や先輩、同僚などに相談することで判断材料を増やし、正しい判断ができるように相談を行います。「どんな方法でもよいから、相手に伝えれば終了」というものありません。タイミング、スピード、伝え方など相手のことを考えて思いやりの気持ちを忘れずに伝えましょう。また相手に正しく理解してもらうよう、わかりやすく手短に伝えることが重要です。常日頃から迅速かつ正確に意見や情報を「伝える術」を磨くことも大切です。

###優先順位（プラオリティ）をつける
上手に仕事をこなすためには、ひとつひとつの業務（タスク）に優先順位をつけることがポイントです。優先度の付け方は最優先は「緊急かつ、重要」、2番目に「緊急ではないが、重要」、3番目に「緊急だが、重要ではない」最後に「緊急でもないし、重要でもない」と非常にシンプルです。
仕事をこなす順番を明確にしておくとで業務そのものの流れが分かりやすくなりますし、自分の仕事の全体をよく把握することにもつながってスムーズに効率的に仕事をこなしていくことができます。
ただ最初のうちは優先順位を自身で決められない場合が多いと思います。そんな時は自分がいま依頼を受けている仕事を上司または依頼者に話してどれから取り掛かったらよいか確認するようにしましょう。

###事前準備（段取り）をしっかりする
自分ひとりでできる仕事は限られます。そのため他人に協力してもらったり、味方になってもらうことが重要です。たとえば自分が不在な時に同僚に仕事を頼むときは普段よりコミニュケーションが取れていれば頼みやすいしそうでない場合は頼みにくいと思います。また仕事を行う際、事前に知識や手順などを調べておけばスムーズに仕事を進めることが出来ます。事前準備（段取り）をしっかりすることは仕事をスムーズかつ効率的に進めるうえで大切なことです。


##最後に
上司であったり同僚などに質問する際は「どうしますか？（どうしたらよいですか？）」ではなく「（僕は、私は）○○と考えています（思っています）」と自分の意思や考えを持ったうえで質問やフォローしてもらったほうがよいと思います。どんなことを考え、どういう意見を持っているのかが大切ですしそうすることによって（色々と考えたり調べたりする訓練が出来るので）成長が望めると思います。また相談を受ける人も選択肢を与えながら聞くようにして頂きたいと思います。最初から答えを与えてしまうと成長は望めません。最初は答えられない人も多いと思いますが、その場合は「考えてからもう一回相談してください」といった宿題として持ち帰ってもらうようにして頂きたらよいと思います。
PHPでは異なるクラスのインスタンスが==になることがある

`==`による比較は、[マニュアル](http://php.net/manual/ja/language.oop5.object-comparison.php)では

> 二つのオブジェクトのインスタンスは、 同じ属性と値 (値の比較は == によるもの) を有し、同じクラスのインスタンスである場合に、 等しいとされます。

具体的には同じクラスであり、かつインスタンス内の全てのプロパティが等しければイコールになります。

しかし直後にはこんなことも書いてあるわけです。

> 拡張モジュール内では、自前で作成したオブジェクトの (== による) 比較方法を独自に定義することができます。


ということで先日[実例を挙げ](https://qiita.com/rana_kualu/items/129b4210ce99e7f50d06#compare_function%E3%81%AE%E6%93%AC%E4%BC%BC%E3%82%B3%E3%83%BC%E3%83%89)ました。

```php
	$x = new \DateTime('2018/01/01 00:00:00');
	$y = new \DateTime('2018/01/01 00:00:00');
	$y->foo = 'bar';
	
	var_dump($x == $y); // true
```

\DateTimeクラスは`==`がオーバーライドされており、`==`のチェックは[`sse`と`us`プロパティだけを見る](https://github.com/php/php-src/blob/php-7.3.0/ext/date/lib/timelib.c#L72)ようになっています。
それ以外のプロパティを突っ込んだとしても、`==`による比較は平然と[trueになります](https://3v4l.org/sAfcH)。

ここで終わっていればまだよかったのですが、[ふと思いついたので試してみた](https://3v4l.org/RtnYA)。

```php
	$x = new \DateTime('2018/01/01 00:00:00');
	$y = new \DateTimeImmutable('2018/01/01 00:00:00');

	var_dump($x == $y); // true
```

クラスが異なるのに`==`が等しくなってしまいました。
さすがにこれはどうなんだ。
Rのコード（Shiny）を配布したい

http://stkdev.hatenablog.com/entry/2017/02/12/204631
昔書いた記事のリライト版になります。
※Windowsでの動作を前提にしています。

# Rのコードを配布したい
Rで書いたコードを配布する手段もだいぶ充実してきました。

- RInnoというライブラリの紹介記事
    - [Shinyアプリのローカル利用（RInno）](https://qiita.com/tanakarian/items/609b550c4b18e5a4b925)
- Jupyter NoteでPythonとRを共存させる試み
    - [Jupyterで1つのノートブック内にRとPythonを共存させる](https://qiita.com/tanakarian/items/609b550c4b18e5a4b925)

など、様々なよい配布・共有手段があるなかで今回は、ポータブル版のRに全部突っ込んでR環境を丸々配布するという力技の紹介です。

# Shinyアプリを配布してみる
## アプリの準備
Shinyアプリを作成して、それをR環境のない人に配布する、ということを考えます。
まずはお手元の環境でShinyプロジェクトを作っておきましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/fecbffde-b632-45c7-63f2-6a05829e05b9.png)
New Projectから選ぶだけ。そのまま動かすとサンプルが起動しますね。

### コード追加

ページを閉じたときにRを終了させる記述を追加しておきます。
app.Rもしくはserver.Rのserver関数の部分を以下を追記します。

- 引数にsessionを追加
- session$onSessionEndedを追加

```r:app.R
# Define server logic required to draw a histogram
server <- function(input, output, session) {
   
   output$distPlot <- renderPlot({
      # generate bins based on input$bins from ui.R
      x    <- faithful[, 2] 
      bins <- seq(min(x), max(x), length.out = input$bins + 1)
      
      # draw the histogram with the specified number of bins
      hist(x, breaks = bins, col = 'darkgray', border = 'white')
   })
   
   # セッション切れたときにRを終了させる
   session$onSessionEnded(function(){
     stopApp()
     q("no")
   })
}
```


## R Portableの導入とライブラリインストール
元の記事から少し改善した部分です。
元記事では必要なライブラリを直接指定フォルダーにコピーする手順にしていますが、依存ライブラリを調べるのが面倒なので、自動でできるようにしましょう。

まず、[R Portable](https://sourceforge.net/projects/rportable/)をダウンロードします。
解凍し、`./App/R-Portable/bin/x64/Rgui.exe`を実行します。
そこで`.libPaths()`を実行します。
ライブラリはここにインストールされます。

```r
> .libPaths()
[1] "C:/Users/[ユーザ名]/Documents/R/win-library/3.5"
[2] "[インストール先]/R-Portable/App/R-Portable/library"  
```
こんな感じにローカル上のwin-libraryフォルダとR Portableフォルダ内のlibraryフォルダが設定されていると思います。
ここで、設定をR Portableのディレクトリのみになるよう書き換えます。

```r
> .libPaths(.libPaths()[2])
> .libPaths()
[1] "[インストール先]/R-Portable/App/R-Portable/library"
```
この状態で、必要なlibraryをインストールします。
`install.packages("shiny")`
これで、`[インストール先]/R-Portable/App/R-Portable/library`に必要なライブラリがインストールされます。

## 起動スクリプト
以下のようなディレクトリ構成にします。
App/
├ ShinyApps/
│ ├ app.R    #shinyアプリソースコード
│ ├ run.vbs　#アプリ全体の起動
│ └ runShinyApp.R #shiny起動スクリプト
│
└ R-Portable/

shinyを起動するスクリプトを記述します。

```r:runShinyApp.R
.libPaths("../R-Portable/App/R-Portable/library")
shiny::runApp("./",port=8888,launch.browser=TRUE)
```
全体を起動するスクリプトはこんな感じ

```vbs
CreateObject("Wscript.Shell").Run "..\R-Portable\App\R-Portable\bin\R.exe CMD BATCH --vanilla --slave runShinyApp.R" & " " & RND & " ", 0, False
```

これで、App/ディレクトリを丸々配布し、run.vbsを実行するとブラウザ上にshiny製のページが表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83530/3b746c57-b540-79ec-e8cc-91ebc165ed61.png)

[元の記事](http://stkdev.hatenablog.com/entry/2017/02/12/204631)や[大元の記事](https://www.r-bloggers.com/deploying-desktop-apps-with-r/)では、ポータブル版のブラウザを使うことで万全な体制（？）にしていますが、今回は簡略版です。古めのブラウザを使っている人に配布する場合はポータブル版ブラウザも設定しておくと安心です。（容量は大変なことになりますが）
Cで作るコンテナもどき　#1

## はじめに
この記事は[FuraITアドベントカレンダー](https://adventar.org/calendars/2899)22日の記事になります。
遅れてごめんなさい。昨日が22日だと思っていました。

また[こちら](https://asahikawa.connpass.com/event/111842/)で発表した内容と近いものになります。多分発表したときのほうが面白いので、気になる方はどうぞご参加ください。

まったくFuraITとは関係ありませんが気にしないで続けていきます。
## 環境
- debian 9 
- kernel 4.9.0-8-amd64

## 作っていく
"#1"ということで、今回はC言語でforkとexec、waitを扱う部分までやりたいと思います。続けていくのかはわかりません。

### fork
まずはプロセスをforkしてあげる必要があります。
Linux特有のライブラリもあるのでWindowsの方は自分でなんとかしてください。

```c
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>

int main(){
  pid_t pid;

  if ((pid = fork()) < 0){
    perror("fork");
    return 1;
  } 
  //子プロセス側の処理
  else if (pid == 0) {
    printf("child process:%d\n",(int)getpid());
    _exit(0);
  }
  printf("parent proces:%d\n",(int)getpid());
  return 0;
}
```
実行結果

```
parent proces:28540
child process:28541
```
こんな感じでした。~~ちゃんと親プロセス側の処理が先に実行されてますね。~~

[Man page of FORK](https://linuxjm.osdn.jp/html/LDP_man-pages/man2/fork.2.html)を見ればだいたいわかるんですが、
forkの返り値は正の値であれば子のプロセスID。0であればforkの成功として、子プロセスに返されます。
なので、pid == 0と指定してあげることで、子プロセス独自の処理をすることができます。

___

### exec
子プロセスを呼び出すことに成功したので、次は実際に子プロセス内部で外部プログラムを実行します。
外部のプログラムを実行するには、exec系のシステムコールを呼び出す必要があります。
今回はexeclを使うことにしました。

```c
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>

int main(){
  pid_t pid;

  if ((pid = fork()) < 0){
    perror("fork");
    return 1;
  } 
  //child process
  else if (pid == 0) {
    printf("child process:%d\n",(int)getpid());
    execl("/bin/bash","",NULL);
    _exit(0);
  }
  printf("parrent proces:%d\n",(int)getpid());
  return 0;
}
```

[Man page of EXEC](https://linuxjm.osdn.jp/html/LDP_man-pages/man3/exec.3.html)　
exec系の説明は長くなるので割愛します。

~~子プロセスから/bin/bashを実行しましたが何も起きません。子プロセスは親プロセスが終了すると、死んでしまうからです。
そのため、子プロセスの終了を親プロセスが待ってあげる必要があります。~~

___

### wait
wait系のシステムコールを用いて子プロセスの終了を待つことができます。今回はwaitpidを使用しました。
sys/wait.hをincludeするのを忘れないようにしましょう。

```c
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdio.h>

int main(){
  pid_t pid;
  int status;

  if ((pid = fork()) < 0) {
    perror("fork");
    return 1;
  } 
  //child process
  else if (pid == 0) {
    printf("child process:%d\n",(int)getpid());
    execl("/bin/bash","",NULL);
    perror("bash");
    _exit(1);
  }
  
  printf("parrent proces:%d\n",(int)getpid());
  if ((pid = waitpid(pid,&status,0)) < 0) {
    perror("wait");
    return 1;
  }
  if (WIFEXITED(status)) {
    printf("pid:%d status:%d\n",(int)getpid(),WEXITSTATUS(status));
  }
  return 0;
}
```
[Man page of WAIT](https://linuxjm.osdn.jp/html/LDP_man-pages/man2/wait.2.html)を見れば全部わかります。
waitpidは、終了を待つプロセスID、終了ステータスを入れる変数、3つ目はoptionとなっていますが(今は関係ない)を引数にします。
WIFEXITED()は子プロセスがexitで終了した際に真となり、WEXITSTATUS()でその終了ステータスを取り出すことができます。
実行結果ですが、psコマンドで親プロセスのID、子プロセスのIDがあることを確認してください。一応この時点でchrootコマンドを用いての動作確認もできるのですが、それは'#2'できっと紹介されるはずなので待っててください。

##　終わり！
'#1'はここで終わりです。気が向いたら'#2'を書きたいと思います。
間違っているところやわかりにくいところがあれば気軽に連絡してください。

##　参考にしたところ
http://chikuwait.hatenablog.com/entry/2017/10/05/001126
Visual Studio Codeをコマンドラインから起動する

VSCodeをターミナルから起動できるように、Windows, Macのやり方:

## Windowsの場合
インストールするとcodeコマンドが入ってPATHも通るから、何もしなくてもコマンドラインから`code .`で起動できる

## Macの場合
Macの場合はデフォルトではターミナルから認識されない。
VSCodeは、`open -n -b "com.microsoft.VSCode"`で起動できるので`.bash_profile`に下記を入れておくと、`code .`で起動できるようになる

`code () { VSCODE_CWD="$PWD" open -n -b "com.microsoft.VSCode" --args $* ;}`

以上
Railsで特定のインスタンスの前後のレコードを入手する

今回はRailsでuserが投稿した記事(今回はnoteとします)の詳細画面で
「次へ」　「前へ」
ボタンを設置します。それのまとめです！
動画だとこんな感じですね。
https://i.gyazo.com/822b4adbf66fe78be9367e84fc890fa2.mp4

編集するのは
・コントローラ
・モデル
・ビュー
です！

# コントローラを編集

```ruby:app/controller/notes_controller.rb

def show
  @note = Note.find(params[:id])
end

```

ここは通常通りにparamsで受け取ってやります！簡単ですね

# モデルを編集

```ruby:app/models/note.rb

class Note < ApplicationRecord
  belongs_to :user

  def previous
    user.notes.order('created_at desc, id desc').where('created_at <= ? and id < ?', created_at, id).first
  end

  def next
    user.notes.order('created_at desc, id desc').where('created_at >= ? and id > ?', created_at, id).reverse.first
  end

end
```

必ずbelongs_toしてください！じゃないと＠noteの前後のレコード取れないので。
後はpreviousメソッドとnextメソッドを定義してあげる感じです！
これで@note.nextとかやれば前後のレコードのインスタンスを取得できます！

#ビューを編集

```ruby:app/views/notes/show.html.haml
.note__index
  .note__index__before
    - if @note.previous.present?
      = link_to note_path(@note.previous) do
        = @note.previous.title
  .note__index__after
    - if @note.next.present?
      = link_to note_path(@note.next) do
        = @note.next.title

```

こんな感じですね。
@note.next.titleとしてやることにより
「お祭りに行ってきた！」などの記事のタイトルが出るようになっています。

また、if文を書いてあげることにより、前後のレコードがない場合は表示させないようにしています！（例えば、最初の記事とか最後の記事とか）

#以上です。ありがとうございました！！
じゃんじゃんコピペしてください！
Node.jsでgRPCを使うときのメモ

### コード生成

dyhnamicにコード生成する場合は、 `Protobuf.js` を使う
staticに事前にコード生成する場合は、 `protoc` を使う

**参考**
https://grpc.io/docs/tutorials/basic/node.html#example-code-and-setup

### クライアントの非同期ハンドリング

eventまたは、callbackを使う

simple callのときはcallbackでよいが、streamのときは複数回結果を受け取る必要があるのでeventを使う
公式サンプルで使い分けが示されてるので、一度呼んだほうがわかりやすい


### クライアント実装のサンプル

https://github.com/grpc/grpc/blob/v1.17.1/examples/node/dynamic_codegen/route_guide/route_guide_client.js
NginxとDockerfileでAPIのスタブを作成する

## スタブとは
プログラムのモジュールをテストする際、そのモジュールが呼び出す下位モジュールの代わりに用いる代用品のことです。下位モジュールが未完成でも代わりにスタブを用いることでテストが可能になります。よくモックと間違えられることがありますが、モックとは別物です。

本記事では、外部のAPIを利用するシステムを構築する際に、そのAPIをNginxとDockerfileを利用して簡単にスタブ化する方法を紹介します。なお、APIのURLの例として以下2通りを利用します。

* /api/v1/users/
* /api/v1/companys/

## スタブファイルの作成

「/api/v1/users/」というURLで以下のようなレスポンスを返却するAPIのスタブファイルを作成します。

```users.json
[
    {
        "id":"1",
        "first_name":"Test",
        "last_name":"Ichiro"
    },
    {
        "id":"2",
        "first_name":"Test",
        "last_name":"Jiro"
    }
]
```

次に「/api/v1/companys/」というURLで以下のようなレスポンスを返却するAPIのスタブファイルも作成します。

```companys.json
[
    {
        "id":"1",
        "name":"Company1"
    },
    {
        "id":"2",
        "first_name":"Company2"
    }
]
```

## Nginxのdefault.confの作成
DockerのNginx公式イメージで作成するのでdefault.confになります。設定は以下の通りです。

```default.conf
server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    # ユーザー情報取得API
    location /api/v1/users/ {
        root   /usr/share/nginx/json;
        index  users.json;
    }

    # 企業情報取得API
    location /api/v1/companys/ {
        root   /usr/share/nginx/json;
        index  companys.json;
    }
}
```

冒頭で紹介した、2つのURLのlocationを記載します。設定の詳細は「[Nginxの静的コンテンツの提供](http://mogile.web.fc2.com/nginx/admin-guide/serving-static-content.html)」を参照ください。

## Dockerfileの作成

Dockerfileを以下の通り作成します。

```Dockerfile
FROM nginx:latest

ADD ./conf.d/default.conf /etc/nginx/conf.d
ADD ./json /usr/share/nginx/json/
```

## 作成した各ファイルのディレクトリ構成
ここまでで作成したファイルのディレクトリ構成は以下の通りにします。

```
├─api-stub  ※作業ディレクトリ
│  │  Dockerfile
│  │
│  ├─conf.d
│  │      default.conf
│  │
│  └─json
│      └─api
│          └─v1
│              ├─companys
│              │      companys.json
│              │
│              └─users
│                      users.json
```

## Dockerイメージの作成

```
docker build -t api-stub-image .
```

## 作成したイメージからコンテナの作成・起動

```
docker run --name api-stub -d -p 8080:80 api-stub-image
```

これで、スタブが出来上がりました。

## 動作確認

以下のように、各APIで作成したスタブファイルが返却されれば成功です。
※1行目と2行目は、Chrome拡張のJSON Viewerが付けてるメタ情報だと思うので無視してください。
![aaaaa.PNG](https://qiita-image-store.s3.amazonaws.com/0/23101/86085209-873f-0f4a-2fe6-267ceef38054.png)
![c.PNG](https://qiita-image-store.s3.amazonaws.com/0/23101/0d6fd22d-5215-e2f8-1f1d-9136c60bdb20.png)


以上です。
BitVisorのVMCS Shadowingの実装について

みなさんご存知の通り，今年BitVisorにIntel CPU向けの[(unsafe) nested virtualizationのサポートが追加されました](https://bitbucket.org/bitvisor/bitvisor/commits/89eeec84cc97bfb1384fcbc863fe2b8e06903644)[^1]．

[^1]: AMD向けには前からあります．

ここで，VMCS Shadowingと呼ばれるNested Virtualizationを高速化するためのCPUの機能が有効であれば使うようになっています．

## 用語
- L0: 大元のハイパーバイザのこと．ここではBitVisor
- L1: L0上で動かすハイパーバイザのこと
- L2: L1上で動くゲストOSのこと

## VMCS Shadowingの概要
VMCS Shadowingは， VMX non-rootのguestが発行するVMREAD/VMWRITE命令をVMEXITせずにCPUが実行する機能です（2013年ごろから登場）．
Intel SDM Vol3の24.10 VMCS TYPES: ORDINARY AND SHADOW あたりに書いてあります．

VMCS Shadowingの設定項目としては，以下のようなものがあります．

- VMCS Region
    - VMCS Revision shadow-VMCS Identifier (先頭4byte)の31bit = 1
        - このVMCSではVMENTRYできなくなる
        - もしCPUが対応していない場合，VMPTRLDは失敗する
- Secondary Processor-Based VM-Execution Controls
    - bit14: VMCS Shadowing = 1
- VMCS guest state
    - Guest non-register state
        - VMCS Link Pointer (64bit）
- VMCS Shadowing Bitmap
    - このbitが1ならshadow VMCSに関わらずVMEXITが発生

VMCS guest stateにあるVMCS Link Pointerで指すVMCSをL1がVMREAD/VMWRITEで読み書きすることになります．
また，VMCS Shadowing用のVMCSは，shadow-VMCS identifierのビットを1にする必要がありますが，VMPTRLDをした後にVMCSのshadow-VMCS identifierを書き換えるには一旦VMCLEARしなければならない点に注意が必要です．

## 実装の方法
単純に考えると，VMCS Shadowingの実装方法は二種類あります．

一つはVMCS Shadowingで利用するVMCSと，L2へVMENTRYする際のVMCSを共有する方法です．
このためには，L2にVMENTRYする際と，L1用にVMCS Link Pointerを設定する際で逐一shadow-VMCS identifierを書き換える + (VMCLEARすることになるので) L2へのVMENTRYにはVMRESUMEではなくVMLAUNCHを常に使うことになります．Host stateの書き換えも必要です．

もう一つの方法はVMCS Shadowing用とVMENTRY用で別々にVMCSを持つことです．
この場合は，L2にVMENTRYする際，Shadowing用のVMCSから適切にデータをVMENTRY用のVMCSへコピーする必要があります．

どちらの実装をするべきなのか，というのはSDMには書いていないように思います．
前者ではVMCLEAR+VMLAUNCHのコストが，後者ではデータコピーのコストが気になる点です．
あまり深く確認していませんが，Xenでは前者，KVMでは後者のように実装されていた気がします．

BitVisorでは後者が採用されています．
この理由の一つはゲストに対してVMCS Shadowing対応する際この方が都合が良かったから...という認識です．（が，コードの詳細確認できてません..）
ちなみに，BitVisor Summitで話を伺ったところ性能的にはVMCS Shadowing用とVMENTRY用でVMCSを共有した方が良かったらしいです．

## VMCS Shadowingの効果
前に測定したら，ESXi on BitVisor上のゲストから直結している別のマシンへのpingのレイテンシが210usから182usに改善しました(-28)．（ベアメタル上では168us)．
ちなみにESXi on KVMでは394us→332us(-53)でした．

ただこれ自分がVMCS Shadowing実装した時のものの評価で，今のBitVisorに入っている実装のものとは異なります．すみません..

## ちなみに
VMCS ShadowingがあってもやはりNested Virtualizationのオーバヘッドは一般に大きく，どう軽量化するかというのは依然課題の一つです．

12/23にリリースされたLinux 4.20のChangeLogをみていたら，KVMにEnlightened VMCSというものが実装されていました．
これはHyper-Vの準仮想化の機能で，L1が作成するL1/L2のVMCSを通常のメモリ上に配置し，VMEXITなしにVMCS操作をおこなうというものらしいです．
以下に説明があります．

- Vitaly Kuznetsov, [A SLIGHTLY DIFFERENT NESTING - KVM on Hyper-V](https://archive.fosdem.org/2018/schedule/event/vai_kvm_on_hyperv/attachments/slides/2200/export/events/attachments/vai_kvm_on_hyperv/slides/2200/slides_fosdem2018_vkuznets.pdf), FOSDEM 2018.

## 参考文献

以下にBitVisorのVMCS Shadowingに関する説明があります(p.33-4)．

- 榮樂 英樹, [BitVisor 2018年の主な変更点](https://www.slideshare.net/bitvisor/bitvisor-summit-72-bitvisor-2018), BitVisor Summit 7, 2018.
バッチ設計時の基本的な要点



### バッチ処理のデータストア
バッチ処理では大量データを扱うことが多いため、まずはそのデータを扱うデータストアを確認する必要があります。バッチ処理の入力データはファイルなのかRDBなのか、バッチ処理した結果をファイル出力するのかRDBに出力するのか等です。このように目的や用途に応じてファイルシステムに保存するのかRDBに保存するのかを検討します。また、ファイルの場合はTSVなのかCSVなのかXMLなのか等のファイル形式も検討します。

### ジョブと順序制御
業務的に意味のある1つのバッチ処理を、ジョブと言います。通常、バッチ処理は多くのジョブで構成されているため、以下を検討する必要があります。

* 何をジョブとするのか
* 各ジョブの実行順序は問題ないか（その実行順序でデータの不整合は発生しないか）
* エンハンス開発等の場合、既存ジョブと実行順序は問題ないか
* オンライン処理とのデータの排他制御（これに関しては、[排他制御（楽観ロック・悲観ロック）の基礎](https://qiita.com/NagaokaKenichi/items/73040df85b7bd4e9ecfc)でも軽く触れています）

### トランザクション管理
RDBを利用したバッチの場合、以下の観点でトランザクション管理を設計する必要があります。

1. スループットやシステムリソースへの影響
2. データ不整合の回避

##### 1. スループットやシステムリソースへの影響
冒頭でも書きましたが、バッチ処理は大量データを扱うことが多いです。それらの大量データに対して一度にコミットすることもできれば、1件ごとのコミットをすることも可能です。大量データに対して一度にコミットする方がスループットが高くなる可能性がありますが、その分RDBの更新ロックを長時間確保することになります。更新ロックの長時間確保は、RDBの特定リソース（ロールバック用領域）を大量に消費する可能性があるため注意が必要です。また、データ量が多いとその分ロールバックに時間がかかったり、データ更新の進捗状況も把握できないため処理時間があまりにも長いと、システム障害（RDBのハングアップ等）と見なしてバッチを強制終了させるかどうかの判断も難しくなります。

##### 2. データ不整合の回避
バッチを並列実行させる場合、ジョブ同士が同じデータを更新するケースを考慮する必要があります。

### リラン時の制御
バッチ処理中に何らかの障害が起因で[アベンド](http://e-words.jp/w/%E3%82%A2%E3%83%99%E3%83%B3%E3%83%89.html)したり[アボート](http://e-words.jp/w/%E3%82%A2%E3%83%9C%E3%83%BC%E3%83%88.html)させたりで処理が中断した場合、そのバッチを再度実行し未処理のデータ更新を続行させる必要があります。こういったケースでバッチを再実行することをリランと呼びます。リランするケースを考慮し、同じバッチを2回以上実行しても更新済みのデータはスキップする等、同じデータの二重更新を避ける等の制御が必要です。よく見かけるのは、更新済フラグ等を設けて制御をする、といった方式です。

### 入力データの検証とエラーハンドリング
バッチ処理の入力データがオンライン処理によるものであれば、オンライン処理の検証ロジックで信頼性が担保されているため、あえてバッチ処理で検証ロジックを入れる必要はないと思います。ただ、入力データが他システムから受領したファイルやユーザーがアップロードしたファイル等の場合、信頼性が不十分なためバッチ処理で検証ロジックを搭載する必要があります。
検証の結果エラーとなった場合、それらをハンドリングする必要がありますが、それにはいくつか選択肢があります。

1. 1件でもエラーが発生すればバッチ処理全体を中断させる
2. エラーが発生したら当該データをスキップさせバッチ処理を継続させる
3. エラーの件数に許容値を設けてそれを超過したらバッチ処理を中断させる

##### 1. 1件でもエラーが発生すればバッチ処理全体を中断させる
この方式は、全てのデータの入力値が妥当でなければバッチ処理を最後まで続行させることはできません。どの単位でデータコミットするかによりますが、最後にまとめてコミットする方式を採用する場合、最後のデータ更新時の入力チェックでエラーが発生した場合、それまで成功していた全ての更新をロールバックし再度やり直し、、といった具合に効率的にはあまりよくありません。

##### 2. エラーが発生したら当該データをスキップさせバッチ処理を継続させる
この方式で重要なのは、エラーが発生したため更新をスキップした旨をログ等に残しておき、後から運用でリカバリ可能な状態にしておくことです。

##### 3. エラーの件数に許容値を設けてそれを超過したらバッチ処理を中断させる
1と2の中間的な考え方で、エラーの件数に許容値を設けそれを超過したらバッチを終了させます。2の方式の場合、スキップデータが多すぎると運用でのリカバリに時間がかかることも想定されるため、リカバリ可能な件数を予め運用担当者と合意をしておき、それを許容値として定義しそれを超過したらバッチを中断させます。

以上です。

## 参考
[アプリケーションアーキテクチャ設計パターン](https://www.amazon.co.jp/%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3%E8%A8%AD%E8%A8%88%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-%E4%B8%89%E8%8F%B1UFJ%E3%82%A4%E3%83%B3%E3%83%95%E3%82%A9%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%86%E3%82%AF%E3%83%8E%E3%83%AD%E3%82%B8%E3%83%BC%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE-%E6%96%89%E8%97%A4-%E8%B3%A2%E5%93%89/dp/4774193038/ref=tmm_other_meta_binding_swatch_0?_encoding=UTF8&qid=&sr=)
メモ：「３０日でできる！OS自作入門 」14日目

## 高解像度・キー入力

1) また性能を測定してみる (a ~ c)
- タイマ 490　個作る
- CPUのJMP命令は飛び先の番地によって実行クロック数が変わるとのこと
    - アセンブリ書くことで治るらしいが、今回はしない方向

2) 高解像度にしよう (d)
- 640x480 に設定
- VESA周りの説明
- qemu-system-i386 上は動かなかった。真っ黒

3) 高解像度にしよう２ (e)
- VBE チェックの機能追加
- これで動きました

![スクリーンショット 2018-12-24 16.32.48.png](https://qiita-image-store.s3.amazonaws.com/0/109145/c2ab3895-0aed-cadb-83ed-94989e0969da.png)

きれいですね。

4) キー入力
- Aのキーを押したときに A　を表示する

![スクリーンショット 2018-12-24 17.07.42.png](https://qiita-image-store.s3.amazonaws.com/0/109145/3c0ba8dc-45fa-e97d-82f3-ed1bf95e2028.png)

- その他にもカウンタ処理をやめたりしている

5) キー入力２
- そのほかのキーも対応
- keymap を作って表示できるもじなら画面に出す
- 他のキーも表示されることを確認

6) おまけ（１）
- テキストボックス作成
- カーソルの点滅
- 文字の入力
    - バックスペース対応

![スクリーンショット 2018-12-24 17.15.22.png](https://qiita-image-store.s3.amazonaws.com/0/109145/a2509df5-6a00-1a05-3bcb-804679cad595.png)

7) おまけ（２）
- ウインドウの移動
- 追加したコードはこれだけ

```c

if ((mdec.btn & 0x01) != 0) {
  /* 左ボタンを押していたら、sht_winを動かす */
  sheet_slide(sht_win, mx - 80, my - 8);
}
```

![window-move.gif](https://qiita-image-store.s3.amazonaws.com/0/109145/f8ee0848-364b-597f-15cb-a4dcbdd8ab35.gif)

かっこいいですね！
Firebase: codelabのチャットチュートリアル - devDependenciesインストールする

どうしても`npm install -g firebase-tools`（Globalインストール）したく（させたく）なかったのでメモ

# 前提

Firebaseを学ぶにあたっての教材は[Firebase Web Codelab ](https://codelabs.developers.google.com/codelabs/firebase-web/)チュートリアルがとても優良なので基本的にはそれに従う。ので、細かいことは書かない。

# devDependenciesで環境を作る
Firebase Web Codelab: [#4 Install the Firebase command line interface](https://codelabs.developers.google.com/codelabs/firebase-web/#3) に書いてあるとおりの内容を以下の手順に変えてみる。

```
$ cd web-start
$ npm init
$ npm install --save-dev firebase-tools
```
で最低限の環境が完成。
ここで手元を一旦コミットしておくと以降の変化がわかるはず。
続けて``firebase init``すると、firebaseの設定やignoreをしてくれる。

```
$ npm run firebase init
? Which Firebase CLI features do you want to setup for this folder? Press Space to select features
, then Enter to confirm your choices.
 ◯ Database: Deploy Firebase Realtime Database Rules
 ◯ Firestore: Deploy rules and create indexes for Firestore
 ◯ Functions: Configure and deploy Cloud Functions
❯◉ Hosting: Configure and deploy Firebase Hosting sites
 ◯ Storage: Deploy Cloud Storage security rules

? Select a default Firebase project for this directory: (Use arrow keys)
  [don't setup a default project]
❯ YOUR-PROJECT (YOUR-PROJECT)
  [create a new project]
```
※長いので一部割愛
上記以降で、firebase上のプロジェクトを選択すると、チュートリアルの``firebase use --add``を実行したのと同等になる（はず）

``firebase.json``で以下が消えてしまっているので戻しておく。これ自体がどのような効果を発揮するかはここでは言及せずに、チュートリアルに従うという意味で意図的な思考停止をしておくとする。

```
+    "headers": [{
+      "source" : "**/*.@(js|html)",
+      "headers" : [ {
+        "key" : "Cache-Control",
+        "value" : "max-age=0"
+      } ]
+    }],
```
echo命令とは（ただ表示するものではない）

画面に文字列を表示する命令は複数存在する。

その中でもechoはPHPでよく使われる命令の一つである。

[phpリファレンス](http://php.net/manual/ja/function.echo.php)のecho命令のマニュアルをみると

>(PHP 4, PHP 5, PHP 7)
echo — 1 つ以上の文字列を出力する

とecho命令は基本的に画面に文字を表示するものとして表現されている。

最終的には、画面に出力しているが

echoがそのまま表示している訳ではないことに注意する必要がある。

echo命令というくらいなので命令を出しているのである。

その命令内容が「**画面に文字列を表示する**」ということである。

シェルコマンドのecho命令が説明としてはわかりやすく

```
$ echo "hello"
```
と命令した時には

```
hello
```
とシェルの内部コマンドであるechoが実行されます。

そして、外部コマンドとしてのechoも複数存在します。

つまり、echoは状況によって異なるものが使われることがわかります。

#まとめ

echo命令は、文字列を表示するというものではなく

命令を出すことによって文字列を表示させていたんですね！

おそらく、実用上echoは表示するものと解釈した方が

わかりやすいということでPHPのリファレンスでは

そのように表記していたのではないでしょうか？

プログラミングは奥が深くて面白いですね！


#文献
[PHPの基本的な文法](http://www.php-labo.net/tutorial/php/)
[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word11715.html)
おもしろいgithubリポジトリ集


# [FizzBuzzEnterpriseEdition](https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition)
* FizzBuzzのエンタープライズ適用でお困りの方必見です
* [HelloWorld](https://gist.github.com/lolzballs/2152bc0f31ee0286b722)もありました

# [Enterprise™](https://github.com/joaomilho/Enterprise)
* エンタープライズな言語です
* `The book Disruption Driven Development – Mastering Enterprise™ `も執筆中だそうです

# [ホワイトハウスのWebサイト](https://github.com/WhiteHouse/fortyfour/issues/3)

# [nocode](https://github.com/kelseyhightower/nocode)
* Write nothing; deploy nowhere.
* [Issue](https://github.com/kelseyhightower/nocode/issues/2805)もなかなか

# [Spoon-Knife](https://github.com/octocat/Spoon-Knife)
* フォークが足りない

# [CIテストをパスする方法](https://github.com/auchenberg/volkswagen)
* 時事ネタ

# [A list of funny and tricky JavaScript examples](https://github.com/denysdovhan/wtfjs)
```javascript
(![] + [])[+[]] +
  (![] + [])[+!+[]] +
  ([![]] + [][[]])[+!+[] + [+[]]] +
  (![] + [])[!+[] + !+[]];
// -> 'fail'
```

# [πfs - the data-free filesystem!](https://github.com/philipl/pifs)
* 100%の圧縮率

# [googlifier](https://github.com/swozniak/googlifier)
* リポジトリよりツールが面白い

# [parrot.live](https://github.com/hugomd/parrot.live)
* ツールが面白い

# [ええええええええええええええええええええええええええええええ](https://github.com/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee)
* [ええええええええええええ?!先越されたああああ](https://qiita.com/wagase/items/867c38f57fe0bce86495)

# 参考
https://github.com/mislavcimpersak/awesome-dev-fun
Cloud FrontでHSTS Preloadに対応する

# はじめに
こちらは、[ZOZOテクノロジーズその2 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/zozo_tech2) 24日目の記事です。

今回は、Lambda@Edgeを使って、CloudFrontにHSTS Preloadを導入してみます。

# HSTS Preloadとは

## HSTS is 何
HSTS(Hypertext Strict Transport Security)は、Webサーバがもつレスポンスヘッダの一種で、「このサーバで接続するときには必ずHTTPSでアクセスしてね」というメッセージをWebブラウザに伝える働きを持っています。

具体的には `Strict-Transport-Security: max-age=31536000;` のようにmax-ageをもたせることで、ブラウザにこの規定の時間がすぎるまではHTTPSを強制化するよう働きかけます。

これによって、仮にユーザが初回HTTPで通信しに来た場合(URLバーでhttp://~で来た場合)も次回以降からはデフォルトでHTTPS通信となり、通信のオーバーヘッドが削減できるというメリットがあります。

## HSTSのpreload属性
しかし、HSTSは一度サーバに接続していないと有効にならないという問題もあり、これを解決すべく作られたのが、preload属性です。

HSTSのレスポンスヘッダに `Strict-Transport-Security: max-age=63072000; includeSubdomains; preload` を持たせた状態で[Googleが公開している登録フォーム](https://hstspreload.org/)にアクセスすることで、preloadを有効にする準備が整います。

### どうなってるのか
ざっくり言うとこんな感じです。

1. フォームに登録する
2. preloadの一覧が入ったJSONに自分のドメインがしばらくすると追加される
3. Chromeなどの主要ブラウザがアップデートされたタイミングで、JSONに自分のドメインが追加され、ブラウザ上でpreloadリストに加わる

こうすることで、主要ブラウザに「あらかじめHTTPS通信を強制するサイト」として、自分のドメインを認識することができるようになります。

# CloudFrontでの問題点

CloudFrontでは、残念ながらHTTPヘッダをきれいに扱う仕組みが提供されていません。また、S3にHSTSをpreload付きで渡すのも、現状不可能です。

そこで登場するのが、Lambda@Edgeです。

## Lambda@Edgeとは
Lambda@Edgeは、CloudFrontのルール定義にLambda(Node.js)を使えるサービスです。詳細については、[弊社テックブログ](https://techblog.zozo.com/entry/lambda-edge)にも書きましたので、そちらをご覧ください。

## 実際のコード
```node.js
'use strict';

exports.handler = (event, context, callback) => {
  const response = event.Records[0].cf.response;
  const headers = response.headers;

  //Set new headers 
  headers['strict-transport-security'] = [{
    key: 'Strict-Transport-Security',
    value: 'max-age=63072000; includeSubdomains; preload'
  }];

  callback(null, response);
};
```
こちらのコードをオリジンレスポンスに対して仕込んであげることで、オリジンからのコンテンツ返却に合わせた形でHSTSをかぶせることができます。

反映が確認できたら、[Googleの登録フォーム](https://hstspreload.org/)にて該当ドメインの申請をしてあげましょう。

**なお、HSTS preloadではmax-ageに下限値があることと、includeSubdomainsも強制化される点があります。ご注意ください。**

反映が完了すると、下記のようにpreloadのリストがすべてのブラウザで有効になることがわかります。なお、こちらの反映にもしばらくの時間を有するため、ご注意ください。

![Screenshot from 2018-12-24 16-57-02.png](https://qiita-image-store.s3.amazonaws.com/0/100275/02a8c606-9555-1112-8e3a-bfc226b96ad4.png)
クリスマスイヴの正しい過ごし方 - 聖なる夜に送りたい。ほら、上腕二頭筋を見て。

皆様こんにちは。

某インフラ系IT企業でエンジニアをしております、dasawaと申します。

※本記事はこちらの「筋肉Advent Calendar 2018」寄稿記事となります。
　　https://adventar.org/calendars/2918
<br/>

先ずお伝えさせて頂きたいのは、上記の通りこの記事は**筋肉**に関する記事であり、**ITは一切関係ない**です。

ただし、健康健全なBodyは仕事を進める上でとっても大切。全ての基礎になります。（無理やり）

#最初に

この記事を執筆しているのは、2018/12/24(祝) 16:00です。

ええ。<font color="Red">クリスマスイヴ</font>です。
<br/>


某地方都市のスターバックス店内でこの記事を執筆しているのですが、周りは<font color="Red">圧倒的なカップル率。</font>

皆、手には交換したであろうプレゼントを携えています。
<br/>



しかし一方。
<br/>


私はジム終わりのスウェット、髪はボサボサ。手には**プロテインとBCAA**を携えています。

一見、完全に負け組アラサー男子がダサい恰好でパソコンに向き合っている、どんでも無く寂しい光景です。

しかし、僕は負け組なのでしょうか？
<br/>


**いいえ。勝ち組です。それも、圧倒的な。**
<br/>

街角インタビューをしたら、100人中98人くらいは**「コイツ、負け組じゃね？」**と思わず口走ってしまいそうな事を現在進行形でしている僕が、**どのようにしてこの狂気的な自信**を付ける事が出来たのか。
<br/>


**その答えは、筋トレにあります。**
<br/>

今回は、筋トレをするメリット・継続方法を紹介します。


#筋トレのメリット

よく言われていますが、筋トレをするとモテるようになるのでしょうか？
<br/>

経験則ですが、Noです。

<br/>

だってそうでしょう。

モテていれば、<font color="Red">こんな寂しいクリスマスイヴ</font>を送っている事はあり得ません。

では筋トレをするメリットは何か？二つお伝えします。

##交渉能力が上がる

エンジニアの方、特に私のような運用系のエンジニアの方は、全般的に交渉能力が弱いです。

お客様や営業、ベンダといったステークスホールダーからの**厳しい要求を跳ね返す事が出来ず**つい首を縦にふってしまいがちです。
<br/>


しかし、筋トレをする事によってこういった要求を跳ね返す事が可能になります。

何故でしょうか？

答えは簡単。
<br/>


貴方がもし筋トレによって屈強なBodyを手に入れた暁には、心のどこかで「**お前、それ以上調子に乗った事を言うと俺の上腕二頭筋で粉砕するぞ**」と思う事が出来ます。

上腕二頭筋で簡単に粉砕できる相手。

**怖くないですよね？**

筋トレをしたら、<font color="Red">これが言わずとオーラから出ます。</font>なので、交渉に強くなることが出来ます。

これはちょっとしたTipsなのですが、それでも意見が平行線の場合は上着を脱ぎながら「**ちょっと、表出て二人で話しません？**」と言います。
<br/>


こうすると、ほとんどの議題はスムーズにまとまります。


##ストレス発散にぴったり

これも僕のような運用エンジニアに強く当てはまります。

運用エンジニアは、日々ストレスとの闘いです。
<br/>


いくら前腕筋群を鍛えぬいたからと言って、暴力はNG。

そんな時は、黙ってベンチプレス。日々のストレスを筋肉に変換する事が出来れば、みんなHappyです。


##継続方法

筋トレの継続のコツは「筋トレしました！」とどこかに報告する事です。

僕の場合は、社内Slackに筋トレのメニューを**一方的**に投稿しまくっています。

こうする事によって、自分に対してプレッシャーをかける事が出来ます。
<br/>


もし筋トレをサボったら、誰かが「**あ、アイツ今日サボったな**」と思うかもしれません。（多分誰も思いませんが。）

もし筋トレをしたら、誰かが「**あ、あの人素敵**」と思うかもしれません。（多分誰も思いませんが。）

もし、こういった場が無いよって人はTwitterで筋トレアカウントを作りましょう。

<font color="Red">共に報告しあえる仲間は大切です。</font>

ポイントは、自ら一人の意思で筋トレを継続するのではなく、身の回りやスキーム・ツールを上手く活用して、**筋トレを長く続けられる仕組みを作る**事です。


#さいごに

最後まで読んで「あ、この記事中身なかったわ」と思ったそこのアナタ。

**ごめんなさい。**
<br/>


ただ、この記事を読んで<font color="Red">一人でも多くの人に筋トレに興味を持っていただき、一人でも多くの人に筋トレを継続してほしい</font>と願っています。

<br/>

ほら、この記事を書いている矢先にすぐ隣の高校生カップルがプレゼントを交換しています。

もしここで僕が発狂し、鍛え抜かれた上腕二頭筋で襲い掛かれば、そのプレゼントも今すぐに真っ二つにする事が可能です。

そんな時、この大切なプレゼントを守る事が可能なのは、<font color="Red">さらに鍛え抜かれた上腕二頭筋</font>です。

いずれ現れる大切な人を守れるように、立派な筋肉を付けましょう。
<br/>


もし大切な人が現れなかったら？

**そんな時はボディビルの大会にでも出ましょう。**
社員数20→50人まで...ちょっとした振返り


アプトポッドの人事をしている小沢です。
入社は最初の大型の資金調達(シリーズA)を実施したちょっとあとの2017年5月で、当時社員数が20名くらいでした。それから約1年半経ち、現在は社員数50名強です。

ちょっと振り返りもかねて、簡単な会社紹介と組織的などんな課題があったか、ポエム的におさらいできればと思います。

#はじめに...会社紹介など
![b1714488-3b04-4523-ab21-df22f51264ff.jpg](https://qiita-image-store.s3.amazonaws.com/0/56243/a945aff1-b79c-e566-c261-902361b4992c.jpeg)
※2017年5月のサーキット走行で車両計測テストの行った時の集合写真。懐かしい...

##大まかな事業内容
- 産業IoTの中でも特に高頻度で発生する時系列データの伝送及びその可視化や監視、遠隔の制御を行う
- 主に産業系メーカーさん内部での研究開発段階におけるPoC支援でのプロダクト導入。その後の商用利用に徐々に移行を目指している
- 対象は車体やドローン、ロボティクスなどなど様々
- 最近では制御/センサーデータだけでなく、動画などのメディアも扱う
- 将来的には国内外問わず利用されるプラットフォームとなるのが目標
<img width="1440" alt="スクリーンショット 2018-12-24 3.59.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/56243/2a50d819-f123-cb32-6df5-e586743a72c6.png">

#組織構成
2017/5で**20名**から2018/12末時点で**53名(社外役員含む)**
大きく管理部と開発とビジネスの3つの組織に分かれている

##職種
![chart (6).png](https://qiita-image-store.s3.amazonaws.com/0/56243/c015851d-e727-aac4-ef15-49ac0ebf2282.png)

- グラフはメインで担当している職域によって分けているので、サーバーとフロントを両方携わるなど、領域を跨って開発している方も複数いる
- 全体の約7割がエンジニア/デザイナーなどの技術職
- エンジニアバックグラウンドの方は(ソリューションアーキテクト職や一部役員など）約8割
 
##年齢
![chart (8).png](https://qiita-image-store.s3.amazonaws.com/0/56243/c6c119cf-afad-469a-5988-9a030c26c3d6.png)

- 平均年齢は約35歳
- toCのベンチャーと比較すると年齢高めな印象ですが、1年前より大分若い方が増えて平均年齢は下がってきた
- 雰囲気としては全体的に落ち着いている(大人な人が多い??)
- 家族持ちも多い

##性別
![chart (7).png](https://qiita-image-store.s3.amazonaws.com/0/56243/0c2e3589-5bfc-a086-d804-031a2696b0a7.png)

- エンジニア多いためどうしても男性比率が高く8割強になっている...



#組織が大きくなるつれてどのような課題があったか？

##世に言うベンチャー50人の成長の壁
[組織はなぜ潰れるのか” ～スタートアップの成長を阻む“成長の壁”の正体～](https://www.wantedly.com/companies/fromscratch/employee_interviews/42557)に30、50、100人規模のそれぞれフェーズで体験する成長な壁を説明していますが。社員数が50人まで増加していくなかで、ここで書いてある「50人の壁」を徐々に実感するようになりました。

>次に「50人の壁」です。ここから徐々に組織の問題が表面化してくるケースが多いようです。組織規模が50人程度に達するのは、1～2回目の資金調達をしてから、だいたい半年～1年後くらいで迎える企業が多いでしょうか。うまく権限移譲が進み、それぞれの部門で“組織長”が生まれつつある組織に、新たに追加で数十人の新規入社者が加わるのがこの時期です。
ここで顕著な事象が
・ 新規接触による採用が急激に増える（＝縁故採用中心でなくなる）
・ 組織内のコミュニケーションの階層が深くなり、複雑化する

**※2017年末全社会議で組織課題の共有をした際のスライド**
![aa.png](https://qiita-image-store.s3.amazonaws.com/0/56243/a177f0b6-fd3b-1f34-04bd-ae4aa38bc3a0.png)


##サービス特性上どうしても組織的な課題になると思っている点
 - 広範な技術レイヤーをカバーする製品を開発しており、更にPoCを繰り返しながら製品の成熟と拡張を行っていくためそれなりの人員数が必要となる
 - まだ未開拓市場を攻めているため、小さなピボットを踏んでいくことがまだまだ重要

異なる技術レイヤー間で連携をし、小さなピボットを踏みながら、それを50人規模で意思疎通をしながらスピード感を持って行ってけるチームの組成って...<br/>**やっぱり時間がかかる！！**

#取り組んだこと
 - 採用のペースを一旦落としてみる<br/> → カオスな状況は避けられたかも
 - プロダクト開発専任のチームを設ける<br/> → プロダクト全体で進捗を合わせた開発サイクルを何回か回せてるようになってきた
 - 個人目標にOKRのような仕組みを入れてみた<br/> → チーム目標を鑑みた上での目標設定をできるようになったのは良いが、評価タイミング以外での振返りがなく運用が全然できていない
 - その他オフィスレイアウトで物理的な距離を変えてみる等々 
  
#所感
組織の問題はその都度どう丁寧にやっていくかが重要でエンジニリング同様、銀の弾丸はないですよね。
ある会社は組織のミッション、バリューが大事だと言いますが、[「奇跡の経営」](https://www.amazon.co.jp/%E5%A5%87%E8%B7%A1%E3%81%AE%E7%B5%8C%E5%96%B6-%E4%B8%80%E9%80%B1%E9%96%93%E6%AF%8E%E6%97%A5%E3%81%8C%E9%80%B1%E6%9C%AB%E7%99%BA%E6%83%B3%E3%81%AE%E3%82%B9%E3%82%B9%E3%83%A1-%E3%83%AA%E3%82%AB%E3%83%AB%E3%83%89%E3%83%BB%E3%82%BB%E3%83%A0%E3%83%A9%E3%83%BC/dp/489346941X)で有名なブラジルのセムコ社には理念やミッション、ビジョン、事業計画や公式の組織図すらないのに成長を続け、低離職率を達成しています。一方でカリスマ経営者がトップダウンで進むところもあったりと...。組織における正しさは千差万別なので、アプトポッドにとって何が本当の正解なのかはいつか見つけられるように今一緒に働いている人達と考えて行きたいと思っています。
[Tips] UICollectionViewCell左寄せ

<img width="718" alt="XQWtB.png" src="https://qiita-image-store.s3.amazonaws.com/0/69002/a8d2e995-8be7-2d36-9d07-414c3205583a.png">

# 概要
UICollectionViewCellを左寄せにする方法まとめTips。

# 方法
## 前提
- FlowLayoutであること。
- 縦スクロール（vertical）であること。


## セルが1種類の場合
<img width="849" alt="スクリーンショット 2018-12-24 16.39.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/69002/1688bf0b-4e1a-3226-8c63-5362aa355843.png">

セルの`contentMode`をLeftに設定。


## セルが複数種類の場合
```swift
final class LeftAlignmentCollectionViewFlowLayout: UICollectionViewFlowLayout {
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        return super.layoutAttributesForElements(in: rect)?
            .reduce(into: [UICollectionViewLayoutAttributes]()) { result, attribute in
                let isFirstCellInColumn: Bool = {
                    if attribute.representedElementCategory != .cell {
                        return false
                    } else if let previousAttribute = result.last,
                        previousAttribute.frame.origin.y + previousAttribute.frame.height >= attribute.frame.origin.y {
                        return false
                    } else {
                        return true
                    }
                }()
                if isFirstCellInColumn {
                    attribute.frame.origin.x = self.sectionInset.left
                }
                result += [attribute]
        }
    }

    // ==================================================
    // レイアウト開始時の動きを制御する必要がある場合、上記と合わせて追加する
    // ==================================================
    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        guard let attribute = super.layoutAttributesForItem(at: indexPath) else {
            return nil
        }
        let isFirstCellInColumn: Bool = {
            if indexPath.item > 1,
                let previousAttribute = super.layoutAttributesForItem(at: IndexPath(item: indexPath.item - 1, section: indexPath.section)),
                previousAttribute.frame.origin.y + previousAttribute.frame.height >= attribute.frame.origin.y {
                return false
            } else {
                return true
            }
        }()
        if isFirstCellInColumn {
            attribute.frame.origin.x = self.sectionInset.left
        }
        return attribute
    }
}
```

<img width="846" alt="スクリーンショット 2018-12-24 16.39.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/69002/ea547b54-3532-2cea-d7d1-8d0d3a9b0752.png">

1. 各セルの`contentMode`をLeftに設定。
2. `UICollectionViewFlowLayout`を継承したカスタムクラスを生成し、行ごとの最初のアイテムの左端が揃うようファンクションをオーバーライドする。
3. 2で作ったクラスをCollectionViewのFlowLayoutに設定する。

※2、3をすることで、復数種類セルが混在しても左寄せになるようになる。



# 備考
知らないとけっこうハマる。。
Raspberry Pi 3B+ とMacとiPhone(テザリング)で、どこでも開発したい

#LANを捕まえられなくなる

ラズパイで色々やってたら、無線を捕まえられなくなり、設定どころではなくなった。
電源起動＋SHIFTで起動して、無線LANの状態を見ても、普通に回線が検出できるっぽい。
ごちゃごちゃ調べるより、色々やりすぎて、設定がわからなくなったので、ここいらでちゃんと整理してみる。

##やりたいこと
1.macからRaspberry piにネットワーク接続するときに、IPアドレス気にせずに繋ぎたい
2.自宅の無線LANが繋がるときは、そちらを、それ以外の時は、iPhoneテザリングで接続したい

つまり、MACとiPhoneとラズパイで屋外で作業ができるようにしたい。

##再インストール

ともかく、電源起動＋SHIFTでブートから再インストール。
特に重要なものは入ってないので完全に初期状態にする。

##mDNS
mDNSを設定することで、簡単に接続できるらしい。
https://qiita.com/takish/items/1a640576caa2d0dfefc4
インストールしてみたが、すでに入っていたらしい。

```:mac_terminal
% ssh raspberrypi.local -l username
```
しかし、なぜかエラーが発生。

https://www.uramiraikan.net/Works/entry-1970.html

知らないうちに使っていたらしい。
ホストキーをリセットする必要がある。

```:mac_terminal
% ssh-keygen -R raspberrypi.local
% ssh raspberrypi.local -l pi
```

とりあえずこれでIPがわからなくても繋がるようになった。

自宅の無線LANとテザリングiPhoneをラズパイに登録して、無線環境はOK。


#ネットワーク設定で無線LANを自動切り替えできるようにする

```:raspberry_pi
$ sudo nano /etc/network/interfaces.d/wlan.conf
```
wlan.confファイルをあたらに作って、そこに切り替えの設定を書き込みます。

参考にしたのはここのリンク先。
https://www.kameneko.com/raspberrypi3-wifi-wpasupplicant/2/

```:wlan.conf
auto lo
iface lo inet loopback
iface eth0 inet manual
auto wlan0
allow-hotplug wlan0
iface wlan0 inet manual
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

iface 接続先の識別子１ inet dhcp
iface 接続先の識別子２ inet dhcp
```

保存した後、リブート

```
$ sudo reboot
```

これで、自動切り替えっぽいことができるようになりました。

このままだとVNCした後の画面解像度がきついので、サイズを適正に変更します。

```
sudo leafpad /boot/config.txt
```

```:/boot/config.txt
hdmi_group=2
hdmi_mode=47
```
今のウェブアプリケーションのパフォーマンスを知ろう

約１年前にGoogleは「[Using page speed in mobile search ranking](https://webmasters.googleblog.com/2018/01/using-page-speed-in-mobile-search.html)」と題して、ウェブアプリケーションにおけるパフォーマンスがユーザーエクスペリエンスに影響すると考えていることを発表しました。

それから先日、Googleは2018/12/19に公式ブログで、検索結果に表示されるページの半分以上でモバイル・ファースト・インデックス (以下、MFI) がすでに使われていると[発表](https://webmasters.googleblog.com/2018/12/mobile-first-indexing-structured-data.html)しました。

つまり今後もMFIがSEOにより影響していく、そしてパフォーマンスが求められていきます。


## いまのパフォーマンスをまずは知ろう
てっとり早く調べたい場合は [PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/) を使おう

PageSpeed Insights とは、CrUX（Chrome User Experience）に基づいて、モバイル端末やパソコン向けのページパフォーマンスに関するレポートと、ページの改善方法を確認することができるウェブアプリケーションです
ここで、次の２つのパフォーマンスを調べることができます

* 速度スコア
* 最適化スコア

ここでのページスコアは 80以上 を目指してください

* Good: 80~ 問題ないよ
* Medium: 60~79 改善の余地あり
* Low: 0~59 見直せ

### クロスブラウザには注意
改善できる項目において、特に次に気をつけてもらいたい

* 次世代フォーマットでの画像の配信

次世代フォーマットは次の３つが挙げられる

* JPEG 2000: Apple推し
* JPEG XR: MS推し
* WebP: Google推し

すべてのブラウザを満たそうと思ったら、次のようになる

```html
<picture>
  <source type="image/webp" srcset="pathto/image.webp">
  <source type="image/jp2" srcset="pathto/image.jp2">
  <source type="image/jxr" srcset="pathto/image.jxr">
  <img src="pathto/image.jpg" alt="alt description">
</picture>
```

４つのフォーマットを満たすのはなかなか大変（テスト量も増えるし）

### 広告タグは棚卸ししよう

ウェブアプリケーションには、集客の観点からリマーケティング（リターゲティング）タグを埋め込む事が多い
しかし、それらの広告タグは、次の問題も一緒に埋め込むことになる

* 非圧縮によるネットワークコストの問題
* メインスレッド上での実行
* キャッシュのTTLが None が多い

GTMを使って埋め込むことが多いので、ぜひ「タグ配信スケジュール」を使って管理してもらいたい
難しい場合でも、半年に１度は棚卸しを

## 詳細なパフォーマンスを知ろう
より詳細なウェブアプリケーションのパフォーマンスを調べたい場合は [Lighthouse](https://developers.google.com/web/tools/lighthouse/?hl=ja) を使おう
上記に上げた PageSpeed Insights は、Lighthouseをデータ元としているためだ

Lighthouse ではパフォーマンスの他に、

* Best Practices
* SEO

なども測定することができる

## おわりに
ウェブアプリケーションを開発するにおいて、速度スコアは大事だ、それはみんなも重々承知していると思う
そのため使っているWeb APIやフレームワークの速度スコアを見ることが多い

しかし、大事なのはユーザエクスペリエンスだ
それは広告タグやクロスブラウザを横断しての結果である

ぜひとも、上記のツールを使い、今を見てもらいたい
Ruby・オプション引数とキーワード引数の違い

Railsチュートリアルの第7章の演習がわかりにくかったのでメモ。

**演習**
>7.1.1 7.1.4で定義したgravatar_forヘルパーをリスト 7.12のように変更して、sizeをオプション引数として受け取れるようにしてみましょう。うまく変更できると、gravatar_for user, size: 50といった呼び出し方ができるようになります。重要: この改善したヘルパーは10.3.1で実際に使います。忘れずに実装しておきましょう。

>7.1.2 オプション引数は今でもRubyコミュニティで一般的に使われていますが、Ruby 2.0から導入された新機能「キーワード引数 (Keyword Arguments)」でも実現することができます。先ほど変更したリスト 7.12を、リスト 7.13のように置き換えてもうまく動くことを確認してみましょう。この２つの実装方法はどういった違いがあるのでしょうか? 考えてみてください。

**gravatar_forヘルパーにオプション引数を追加する**

```app/helpers/users_helper.rb
 module UsersHelper

  # 引数で与えられたユーザーのGravatar画像を返す
  def gravatar_for(user, options = { size: 80 })
    gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
    size = options[:size]
    gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
    image_tag(gravatar_url, alt: user.name, class: "gravatar")
  end
end
```

オプション引数だと、optionsという変数に、ハッシュ{ size: 80 }が代入される。
sizeをURLに使うためには、size という引数に、ハッシュ options[:size] を代入する必要がある。

**gravatar_forヘルパーにキーワード引数を追加する**

```app/helpers/users_helper.rb
 module UsersHelper

  # 引数で与えられたユーザーのGravatar画像を返す
  def gravatar_for(user, size: 80)
    gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
    gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
    image_tag(gravatar_url, alt: user.name, class: "gravatar")
  end
end
```
キーワード引数の場合、sizeという変数にデフォルト値として80が追加される。
sizeという変数を指定しなくても、このまま使うことができる。

（あんまり自信がない）

参考：[Railsチュートリアル](https://railstutorial.jp/chapters/sign_up?version=5.1#cha-7_footnote-ref-6)
fluentdのインストール

やってみたのでメモ

# 前提
- CentOS7

# 手順
1. 予め時刻を合わせる
2. 必要に応じて、次の行を追加してネットワークカーネルパラメータをチューニングする

    ```
    # vi /etc/sysctl.conf
    ```
    
    ```sysctl.conf
    net.core.somaxconn = 1024
    net.core.netdev_max_backlog = 5000
    net.core.rmem_max = 16777216
    net.core.wmem_max = 16777216
    net.ipv4.tcp_wmem = 4096 12582912 16777216
    net.ipv4.tcp_rmem = 4096 12582912 16777216
    net.ipv4.tcp_max_syn_backlog = 8096
    net.ipv4.tcp_slow_start_after_idle = 0
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.ip_local_port_range = 10240 65535
    ```

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

    ```
    # curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent3.sh | sh
    ```

4. fluentdを起動する

    ```
    # start td-agent.service
    ```

5. サンプルを送る

    ```
    # curl -X POST -d 'json={"json":"message"}' http://localhost:8888/debug.test
    ```

6. ログが記録されているかどうか確認する

    ```
    # tail /var/log/td-agent/td-agent.log
    ```
    
    ```td-agent.log
    debug.test: {"json":"message"}
    ```

# 参考
- [Before Installing Fluentd](https://docs.fluentd.org/v1.0/articles/before-install)
- [Installing Fluentd Using rpm Package](https://docs.fluentd.org/v1.0/articles/install-by-rpm)
CSS疑似要素、疑似クラスのコロンの数。1つ2つの違い


今更ですがCSSのコロン2つ付ける場合の
定義を明確にまとめてみました。
なんとなくでなく、わかって使うようにしたい。


#回答：疑似クラスは「:」、疑似要素は「::」

CSS3より擬似クラスと疑似要素でコロンの記述が変更となった。
ブラウザではコロン1つでもエラーにならない。

##疑似クラス 一覧

コロン1つ「:」を記述する。

```
:active
:checked
:default
:defined
:disabled
:drop 
:empty
:enabled
:first
:first-child
:first-of-type
:focus
:focus-visible
:focus-within
:host
:host()
:hover
:indeterminate
:in-range
:invalid
:lang()
:last-child
:last-of-type
:left
:link
:matches() 
:not()
:nth-child()
:nth-last-child()
:nth-last-of-type()
:nth-of-type()
:only-child
:only-of-type
:optional
:out-of-range
:placeholder-shown 
:read-only
:read-write
:required
:right
:root
:scope
:target
:valid
:visited
```

>2018/12/24現在 実験中の擬似クラスは除く


##疑似要素 一覧

コロン2つ「::」を記述する。

```
::after (:after)
::before (:before)
::cue (:cue)
::first-letter (:first-letter)
::first-line (:first-line)
::selection
::slotted()
```

>2018/12/24現在 実験中の擬似要素は除く


##参考

CSSの擬似要素と擬似クラスの違いを明確に – YATのblog
https://wp.yat-net.com/?p=4505

CSSの:afterと::afterどっちが正しい？ 疑似クラスとか疑似要素って何？ | 初代編集長ブログ―安田英久 | Web担当者Forum
https://webtan.impress.co.jp/e/2015/12/08/21670

疑似要素 (Pseudo-elements) | MDN
https://developer.mozilla.org/ja/docs/Web/CSS/Pseudo-elements

疑似クラス | MDN
https://developer.mozilla.org/ja/docs/Web/CSS/Pseudo-classes
Eclipseでtomcatを停止した際にtomcatのプロセスが残っている場合の対処法

Eclipseでtomcatを停止した後、もう一度起動すると、ポートが使われている旨のエラーメッセージが表示されたり、Spring bootの場合は"The Tomcat connector configured to listen on port 8080 failed to start. The port may already be in use or the connector may be misconfigured."というメッセージがEclipseのコンソールに表示されたりすることがある。
これらのエラーはtomcatを停止した後もtomcatのプロセスが残っている場合に発生する。そのため、もう一度同じポートでtomcatを起動するには、tomcatのプロセスを一度停止する必要がある。ここではtomcatのプロセスを停止する3通りの方法を説明する。なお、以下の環境想定している。

- 環境

OS: macOS Mojave
Eclipse version: Photon Release (4.8.0)
tomcat8

### tomcatのプロセスを停止する方法

- アクティビティモニタでプロセスを停止する。
  1. アクティビティモニタを開く。
  2. アクテビティモニタに表示されている"java"というプロセス名を探す。(アクティビティモニタにカーソルを当て、"j"キーを押すと探せる。)
  3. "java"の上でダブルクリックすると、ウィンドウが出るので、そのウィンドウの終了ボタンを押す。
  4. 「このプロセスを終了してもよろしいですか?」と表示されるので、終了ボタンを押す。

- topコマンドでプロセスのPIDを調べて終了する。
   1. terminalを開く。
   2. terminalの画面で以下のコマンドを実行。

```terminal
> top | grep java  
```
すると、"java"のプロセスが表示され、一番左端にPIDが表示されるのでこれをコピー。
3. 以下のコマンドを実行。

```terminal
> kill <コピーしたPID>
```

- pkillコマンドでプロセス名を指定して終了する。
 1. 以下のコマンドを実行。

```terminal
> pkill java
```



以上です。
tomcat触りたての頃は、はまる人もいると思うので、その助けになれれば幸いです。
Clova公式SDKのメソッドよく使うやつ(Node.js)

# install

[ClovaスキルをLambdaで開発し始める時の手順をまとめた(Node.js)](https://qiita.com/imajoriri/items/de8cd992c4a56d0c5bca)

# スロット

```js
// スロットをobjで取得
slots = responseHelper.getSlots();

// 一つづつ取得（fruitというスロットの場合）
fruit = responseHelper.getSlot("fruit");
```

# sessionAttributes

## 取得

```js
var sessionAttributes = responseHelper.getSessionAttributes();
```

## 保存

```js
responseHelper.setSessionAttributes(sessionAttributes)
```

# Speech系

```js
// 通常
responseHelper.setSimpleSpeech(
  clova.SpeechBuilder.createSpeechText(``)
);

// reprompt
responseHelper.setSimpleSpeech(
  clova.SpeechBuilder.createSpeechText('リプロンプトだよ！'), true
);
```

# session終了

```js
responseHelper.endSession();
```

# インテント名取得

```js
responseHelper.getIntentName();
```

# SessionID取得

```js
responseHelper.getSessionId();
```

# User情報

```js
responseHelper.getUser();

{
  "userId": "...",
  "accessToken": "..."
}
エラーを出さずに最頻値を得たいとき

厳密でなくて良いので代表値として1個に絞るために最頻値を使いたい場面で、
statistics.modeでは同率1位のときのエラーを吐くので使いにくい。

やや無駄があるが、collections.Counterクラスを使うと良いかもしれない。

```python
import statistics

x = ['A', 'A', 'B', 'B', 'C']

statistics.mode(x)
# StatisticsError: no unique mode; found 2 equally common values
```

```python
import collections

x = ['A', 'A', 'B', 'B', 'C']

collections.Counter(x).most_common()[0][0]
# A
```

AとBとどちらが選ばれるかは、たぶん保証されない。
ビット演算を利用してべき集合を作成する。

参考: [「C#でサイズnの順列をすべて生成したい。」](https://qiita.com/neko_the_shadow/items/e6a931b8a9193b47fcd3)

表題のとおり「ビット演算でべき集合を作成する」ことがあったので、その際のメモになります。なお以下のサンプルはC#を利用していますが、内容としてはほかの言語でも通用するものと思います。

単純な内容のため、実装方法はさまざまにあると思いますが、とりあえずforループをつかって"べた"に書いてみます。

```csharp
int n = 5;
for (int bit = 0; bit < 1 << n; bit++)
{
    var permutation = new List<int>();
    for (int i = 0; i < n; i++)
    {
        if ((bit & (1 << i)) != 0)
        {
            permutation.Add(i);
        }
    }
    Console.WriteLine("[" + string.Join(",", permutation) + "]");
}
```

以上のプログラムは、n個の集合から作成されるべき集合を表示するものです(表示内容は後述)。注意としては整数型としてintを利用しているため、nがあまりに大きくなるとオーバーフローを起こし、プログラムとして破綻する可能性があります。

せっかくC#を利用しているということもあり、全く同じ内容をLINQで実装してみたいと思います。

```csharp
int n = 5;
var permutations = Enumerable.Range(0, 1 << n)
                             .Select(bit => Enumerable.Range(0, n).Where(i => (bit & (1 << i)) != 0));
foreach(var permutation in permutations)
{
    Console.WriteLine("[" + string.Join(",", permutation) + "]");
}
```

全般的に記述がシンプルになりますね(´・ω・｀)

---

ふたつのプログラムの表示結果はどちらも次のようになるはずです。

```
[]
[0]
[1]
[0,1]
[2]
[0,2]
[1,2]
[0,1,2]
[3]
[0,3]
[1,3]
[0,1,3]
[2,3]
[0,2,3]
[1,2,3]
[0,1,2,3]
[4]
[0,4]
[1,4]
[0,1,4]
[2,4]
[0,2,4]
[1,2,4]
[0,1,2,4]
[3,4]
[0,3,4]
[1,3,4]
[0,1,3,4]
[2,3,4]
[0,2,3,4]
[1,2,3,4]
[0,1,2,3,4]
```