Stack Overflowの使い方

# Stack Overflowとは

* **プログラミングに関する**題材を扱う、**英語の**QAサイト
* https://stackoverflow.com/

## 類似のQAサービスと比較した際の特色

* 質、量ともに圧倒的
    * 英語はユーザーの分母が違うので必然的にそうなる
* 集合知を作ることを目的にする文化がある
    * 類似サービスは質問者が直面している問題を解決することに主眼があり、他の開発者にも役立つ知識をQAの形で残そうという意識はそこまでない
* 集合知を作る文化を醸成するシステムが存在する
    * 良い回答を投稿者一人が決めるのでなく集団の投票によって決める（これにより客観性が確保できる）
    * 良い質問、良い回答を行ったユーザーは、*reputation*（信用度）と呼ばれるスコアを獲得し、これを貯めることで、様々な*privileges*（権限）を得ることができる（良い質問、良い回答をしようとするインセンティブが働く）

下2項目については一部の他サービスも追随しているのでもはやStack Overflow独自の点というわけでもないが、それでもStack Overflowはこういった文化やシステムが類似サービスの中では特に強い、という点は覚えておいてよい。

## 我々日本語圏ユーザーのStack Overflowに対する向き合い方

Googleでよく上の方に引っかかるサイトという認識で止まっている人が大多数なのではないだろうか？
わからないことを質問するなど、Stack Overflowで実際に活動している人は少ない。

## Stack Overflowで質問するメリットはあるのか

だからと言って、無理にStack Overflowで質問してもそれに見合った利益はなかなか得られないのではないかというのが個人的な意見。理由は以下。

* 英語力が十分でない状態だと、質問文を作るだけで半日くらいかかってしまう
* 回答者も不慣れな英文から意味を読み取るのに苦労し、なかなか適切な回答ができない
* 日本ローカルなソフトウェアの質問には弱い
* 他サービスに比べ高クォリティな回答が素早く来るという噂があるが、自分の場合はまったくそんなことはなかった（私怨）

英語力が十分にない場合、純粋な質問目的で臨むのはコスパが悪い。
逆に言うと、**英語力向上や質問力向上の練習を兼ねて質問するのにはとても向いており**、その目的で使うならば非常にオススメである。

## プログラミングに関する題材を扱う日本語のQAサイト

あなたの当面の目的が問題の迅速な解決にあり、英語力の向上などどうでもよいというのであれば、Stack Overflowの代替として以下を検討してみてもよい。

* [teratail](https://teratail.com/)
    * おすすめ。
* [QA@IT](https://qa.atmarkit.co.jp/)
    * こっちは自分はよく知らないので何とも言えない。
* [スタック・オーバーフロー](https://ja.stackoverflow.com/)
    * Stack Overflowの日本語版。個人的には質問・回答の量が少なく下火に見える。
* 番外: ~~Qiita~~
    * 規約上明示的に質問の制限はされていないが、質問よりも知識を記録・共有する場所だと認識している人が多い。サイトの仕組み上質問にもあまり向いていないのでおすすめしない。

## 検索ワードを工夫すれば質問するまでもないかもしれない

また、検索ワードをもっと工夫すれば、わざわざ質問するまでもなく同じような他人の質問が見つかる可能性は高い。
以下のよくある検索ワードのパターンを知っておくと無駄な英文を書かずに済むかもしれない。

* エラーメッセージをダブルクォーテーションで囲ったもの
    * ダブルクォーテーションで囲うと完全一致となり、同じエラーメッセージで悩んでいる人に出会いやすい
* How to ～
    * 何かをする方法がわからないときに
* ～ not working
    * 何かが動かないときに
* ～ vs ～
    * 何かと何かのどちらを使えばいいかわからないときに
* in ～
    * 言語や環境を限定したいときに末尾にくっつける

# Stack Overflowで質問をしたい人向けのガイドライン

それでもなおStack Overflowで質問をしてみたい人に道を指し示すのが[Help Center](https://stackoverflow.com/help)というページである。
ここにはStack Overflowの仕組みや、よい質問をするにはどうすればよいかといったガイドが記載されている。
が、こんな長ったらしいガイドを英語で読みたくもないだろう。
日本語版スタック・オーバーフローの[ヘルプ センター](https://ja.stackoverflow.com/help)がほぼ同内容なので、まずはそちらに目を通しておくことをおすすめする。
以下は、ヘルプ センターの内容の中でも、私が特に重要あるいは補足が必要と感じる内容である。

## ユーザー登録は必須

日本語版スタック・オーバーフローはユーザー登録しなくても質問できるが、英語版Stack Overflowはユーザー登録必須である。
日本語版のヘルプ センターはとても参考になるが、このような細かい違いもある。

## Stack Overflowでしてよい質問

プログラミングに関わる具体的な問題を解決しようとする質問がStack Overflowで期待される質問である。
我々エンジニアはプログラムのみを書いているのではなく、設計、開発手法、チームマネジメント、マネタイズといった分野にも興味があるものだが、それらに関する質問はStack Overflowでは*off-topic*（トピックから外れている）と見なされる。

## Stack Overflowでしがちだがしない方がよい質問

* プログラミングの宿題を貼り付けただけの質問
    * ただし、自分がどこまでできていて何がわからないのかしっかり書けているのなら宿題の質問もしてよい。
* おすすめの本やツールのアドバイスを求める質問
    * 明確な回答が存在しないことと、Stack Overflowをスパムの温床にしかねないことから、*off-topic*とされている。
* 特定のソフトウェアやハードウェアを想定しない、情報科学に関する一般的な質問
    * それ専用のサイトとして[Computer Science](https://cs.stackexchange.com/)がある。ただ[Big-O記法について簡潔に説明してください](https://stackoverflow.com/questions/487258/what-is-a-plain-english-explanation-of-big-o-notation)のような質問もあり、別に両サイトが原理主義的に使い分けられているわけではない。強いて言うとComputer ScienceではBig-O記法の数学的な定義を回答として期待することになり、Stack Overflowでは実用上の利用方法を回答として期待することになるだろう。このようにサイトのトピックとして扱う話題に向き不向きがある。
* サーバー管理、ネットワーク管理、インフラ管理に関する専門的な質問
    * それ専用のサイトとして[Server Fault](https://serverfault.com/)がある。これもサイトのトピックとして向き不向きがあるという話である。

## 質問の仕方

質問をする際の流れやコツを伝えていく。

### 質問の前に検索

まず検索する。検索に検索を重ねる。
たいていのことは誰かがすでに試していて、あなたが新たに質問するまでもないことも多い。
また、結局役に立つ情報が見つからなかったとしても、どのような情報が既にあって、それらはどう役に立たなかったのかという新たな情報は、これから質問をするにあたってあなたの理解も回答者の理解も助ける。

### 質問入力画面

質問が必要であることがわかったらいよいよ質問する。
トップページの目立つところに*Ask Question*というボタンがあるのでクリックする。

質問入力画面はタイトル入力欄、本文入力欄、タグ入力欄に分かれる。

![質問入力画面](https://qiita-image-store.s3.amazonaws.com/0/106760/a6ecadd1-4d90-a371-13bd-0280eb0e8109.png)

タイトル入力欄は一番上にあるものの、タイトルをつけるのは最後に回した方がよいかもしれない。
タイトルとは質問を一文で要約したものであるから、本文を書き終わって、自分が本当は何を聞きたいのか整理された状態で決めた方がよい。

### コードブロックの書き方

質問の本文は[Markdown](https://stackoverflow.com/editing-help)で記述するのだが、コードブロックの記法が独特なので説明しておく。

```md
This is the example code.

    const message = "Hello, world!";
    console.log(message);

Thanks.
```

このように、行頭に半角スペースが4つある行がコードブロックとなる。
QiitaやGitHubとは記法が異なるので注意。

Stack Overflowは言語を推測して勝手にシンタックスハイライトを行ってくれるが、特定の形式のコメントを付加することで、あえて言語を明示的に指定することもできる。

```md
This is the example code.

<!-- language: lang-js -->

    const message = "Hello, world!";
    console.log(message);

Thanks.
```

言語によって、`lang-js`の部分を書き換える。
利用可能な言語のリストは[この回答の下の方](https://meta.stackexchange.com/questions/184108/what-is-syntax-highlighting-and-how-does-it-work/184109#184109)にあるのでそちらを参照してほしい。

### 実行可能なコードブロック

JavaScriptの質問ならばその場でコードを実際に動かせるようにすることもできる。
例えば以下の画面で*Run code snippet*を押すと実際にコードが動く。

![実行可能なコードブロックの例](https://qiita-image-store.s3.amazonaws.com/0/106760/e1bf505a-c646-b8d9-607c-ee4827e7ff6d.png)

そのようなコードブロックを作りたい場合、本文入力欄の上部にある以下のボタンをクリックすればよい。
すると専用のエディタが開く。

![実行可能なコードブロックのエディタ](https://qiita-image-store.s3.amazonaws.com/0/106760/477c036f-8d8c-2a35-b64b-faec38d1f1ed.png)

### サンプルコードは最小限の、自己完結した、確認可能なものでなければならない

別に質問には必ずサンプルコードを載せないといけないわけではない。
もっとも、サンプルコードは万国共通語なので、あった方がわかりやすい質問になることはかなり多い。

サンプルコードを載せる場合、問題が起きているソースコードをそのまま載せて**はならない**。
サンプルコードは、問題を理解するのに必要最低限であり、かつ問題を再現するのに必要な情報がすべて入っており、かつ当たり前だが机上で書いたコードでなく実際に問題が再現することを確認したコードでなければならない。

そのようなサンプルコードを作ろうとする段階で問題が解決してしまうことも多い。
しかしそれは恥ずべきことではない。

### タグをつける

質問に関連するタグを5つまで入力できる。
新しいタグを作ることは基本的にできない[^1]ので、すでに存在するタグの中から適切なものを選ぶ。

[^1]: 一応*reputation*が1500に到達すると可能。

### タイトルをつける

タイトルとは質問を一文で要約したものである。
うまい表現が思いつかないから詳細は本文で補足すればいいやなどと考えて**はいけない**。
回答者はタイトルに対して回答しようとするものと思った方がよい。
タイトルがぼやけていたり不正確だったりすると回答もトンチンカンなものが返ってくる。（実体験）

上の方で書いたよくある検索ワードのパターンはほぼそのままタイトルのつけ方に流用できる。
ほかに、How can I ～ ? や Why does ～ ? といった表現もお決まりである。

### 見直す

書き上げたら最初から最後までよく見直し、推敲する。
また、質問文を書くと、Stack Overflowが質問の文章を自然言語処理して、関連しそうな質問をサジェストしてくるので、タイトルから判断して必要そうなものには目を通しておく。
見落としていただけで、すでに同じような内容の質問がされていた、ということは時々ある。

### 投稿する

*Post Your Question*というボタンを押すと質問を投稿できる。

投稿ボタンの下に*Answer your own question*というチェックボックスがあるが、これはチェックを入れなくてよい。
これは自分の質問にセルフで回答をする場合につけるチェックボックスである。
知識をQAの形でまとめておくとわかりやすくなるという理由で、Stack Overflowでは真の質問ではないセルフQAが認められている。

## 質問の例

以下は[私が実際にした質問](https://stackoverflow.com/questions/34458407/why-does-not-this-case-expression-cause-a-syntax-error)。
ちなみに質問した後、他のユーザーから校正を食らった。（そして以下に載せているのは校正後のもの）
文法的な間違いや不明瞭な文章、不適切なタグなどは他のユーザーに校正されることがある。

### タイトル

Why does not this case expression cause a syntax error?
なぜこのcase式は文法エラーを起こさないのか？

### 本文

I wrote a case expression like

```ruby
case x
when "one" "I"
when "two" "II"
end
```

It does not cause a syntax error, and always returns `nil` regardless of the value of `x`. I think it should cause a syntax error, but the reality is not the case. Why?

次のようなcase式を書きました。

```ruby
case x
when "one" "I"
when "two" "II"
end
```

このcase式は文法エラーを起こさず、`x`の値にかかわらず常に`nil`を返します。私はこのcase式は文法エラーになるべきだと思うのですが、実際はそうではありません。なぜですか？

### タグ

`ruby`, `syntax`, `string-literals`

## *comment*（コメント）について

質問をすると、回答が一発でつくことも無いわけではないが、たいていはなんらかの*comment*と呼ばれるものがつく。
質問と回答のそれぞれにぶらさがる形でくっついているものが*comment*である。

![commentの場所](https://qiita-image-store.s3.amazonaws.com/0/106760/d6347b0f-057a-1592-199e-34abe46d71aa.png)

*comment*は、以下のような質問にも回答にもそぐわない発言をするためのものである。

* 質問や回答の不明点をより明確にしてほしいという再質問
* 質問や回答のよくない点を改善してほしいという提案
* 回答に直接つながらないが役立つと思われる補足的な情報

*comment*で返事をしたり質問文を編集したりして、ついた*comment*に対応しておく。
返事をする際、返信先を`@～`で指定できる。（これにより相手に通知がいく）

## 回答の*accept*（承認）について

回答が1個以上ついた場合、その中からベストアンサーに相当するものを1つ選ぶことができる。
これを*accepted answer*（承認された回答）と呼ぶ。

回答を*accept*するには回答の横にある緑のチェックマークをクリックする。
これによりその質問が解決済みであることが一目で分かるようになる。
回答がついて問題が解決したら、必ず最良の回答を*accept*しておく。

## よくあるトラブル

### 回答が来なくて結局自己解決してしまった

セルフで回答してよい。
なお、自分の質問に自分で回答した場合、自分の回答を*accept*するには48時間待つ必要がある。

### 回答に相当する内容が*comment*に来た

該当*comment*の発言者に*comment*を回答として書き直してもらえるよう伝え、回答を改めて*accept*する。
*comment*は本来回答を書く場所ではない。

### 質問の横にある数字がマイナスになってしまった

質問の横にある数字は*votes*（票）といって、*upvote*（プラス票）の数 - *downvote*（マイナス票）の数である。
よい質問には他のユーザーから*upvote*が、ひどい質問には他のユーザーから*downvote*が贈られる。

目安として*votes*が-3以下になったら空気を読んで質問を削除した方がよい。
おそらく、至らなかった点を*comment*で具体的に指摘されているはずなので反省する。

## *reputation*（信用度）システムについて

各ユーザーはそれぞれ1以上の*reputation*と呼ばれるスコアを持つ。初期値は1。

![reputationの表示場所](https://qiita-image-store.s3.amazonaws.com/0/106760/5d7df13e-9960-3aaf-b794-4aebce7a2067.png)

基本的には、良い質問や良い回答をして他のユーザーから*upvote*（プラス票）を得ると*reputation*が増加する。
逆に、ひどい質問やひどい回答をして他のユーザーから*downvote*（マイナス票）をもらうと*reputation*が減少してしまう。
もっとも、どれだけ*downvote*されようが*reputation*は1で下がり止まる。

*reputation*が特定の値に到達すると、Stack Overflow上の便利な機能を使用できる*privileges*（権限）が解放されていく。
だが、質問と回答をするだけなら*reputation*が1でもできる。

具体的に、*reputation*は次のようなときに増減する。
また、これ以外では増減しない。シンプル！

|増減値|条件|
|---|---|
|+5|自分の質問に*upvote*が一つつく|
|+10|自分の回答に*upvote*が一つつく|
|+15|自分の回答が質問者によって*accept*（承認）される[^2]|
|+2|自分の質問についた他ユーザーの回答どれか一つを*accept*（承認）する[^3]|
|-2|自分の質問に*downvote*が一つつく|
|-2|自分の回答に*downvote*が一つつく|
|-1|他ユーザーの回答を*downvote*する[^4]|

[^2]: このように、*reputation*を稼ぐには自分の得意分野の質問に回答していくのが手っ取り早い。
[^3]: その質問が解決済みであることが一目でわかるようになるので、推奨のため*reputation*が2得られるようになっている。ちなみに、自分の質問に自分で回答したものを*accept*しても*reputation*は得られない。
[^4]: *downvote*の乱用を防ぐため。一方他ユーザーの「質問」を*downvote*しても*reputation*は減らない。Stack Overflowは曲がりなりにも回答を試みた者には多少優しいが、クソ質問に対しては厳しい。

## *privileges*（権限）について

詳細は[Privileges](https://stackoverflow.com/help/privileges)のページを見てほしいが、重要なものを抜粋すると以下のようになる。

|*reputation*|得られる権限|
|---|---|
|10|*remove new user restrictions*<br>質問や回答に9個以上のURLを貼り付けられるようになる。質問・回答の回数制限が緩和される。（どれくらいなのか詳細不明）|
|15|*vote up*<br>他ユーザーの質問・回答に*upvote*できるようになる。|
|50|*comment everywhere*<br>他ユーザーの質問とそれに対する回答に*comment*できるようになる。（自分の質問とそれに対する回答への*comment*は*reputation*が1でもできる）|
|75|*set bounties*<br>48時間以上経った自分または他ユーザーの質問に*bounty*（お礼）を設定できる。回答が早く欲しい質問に対して、自分の*reputation*を元手として懸賞金を設定することができるシステム。|
|125|*vote down*<br>他ユーザーの質問・回答に*downvote*できるようになる。|

# まとめ

* Stack Overflowは集合知を作ることを目的にするサイトであり、それを*reputation*というスコアシステムが支えている。
* Stack Overflowは英語力向上や質問力向上の練習を兼ねて質問するのにはおすすめ。純粋な質問用途だと微妙。
* 迷ったら[Help Center](https://stackoverflow.com/help)を見ればよい。