$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

「体系的に学ぶ安全なWebアプリケーションの作り方」再読した

ユーザアカウント周りの実装で気をつけるべきことをもう一度学び直すために「体系的に学ぶ安全なWebアプリケーションの作り方」を再読した。

以前読んだ時はXSSとかSQLインジェクションとかCSRFとかの特に基本的な部分に関して頭に入ってきてたとけど、今回はアカウント周りとターゲットを決めたのでクッキー周り、セッション周りについて重点的に学ぶことができた。とくに5章にはユーザアカウントの登録や管理、メールアドレス変更、パスワード変更など、ユーザアカウント周りを実装するにあたってまさに必要な情報が書いてある。

サービスを作るにあたってアカウント周りに関することをやることは多いので、そういう時にはもう一度読んでみると良さそうと思った。

プロジェクトを成功させるために最初におこなっていること

ディレクター時代に仕事でプロジェクトを受け持つ時にどうやったら成功させることが出来るのかについていろいろ考えていた。僕は開発フローをいろいろ考えるのが好きなのだけど、実際に自分がリーダーシップを取ってプロジェクトを進めることを経験すると、そもそもその前に考える・決めるべきことがたくさんあるということが分かったので、ブログに書いておこうと思う。

ここで言うプロジェクトとはサービスを一から作ったり、サービスの一機能を作ったり、受託案件一つだったりを指す。特に開発プロジェクトに限定するものでもない。

プロジェクトを成功に近づけるためには、まずプロジェクトの開始時に、プロジェクトの5W1Hを明確にし、個々のメンバーの責任範囲を決め、それらを一つの場所にまとめておくということをしておくと良いと考えている。

5W1Hを決める

すごい基本的なことだけど、プロジェクトをやる上でやはり5W1Hは大事である。一番最初に明確にしておいたほうがよい。

自分の場合、以下の様に5W1Hを明文化している。

  • このプロジェクトはなぜ行うのか、どういう目的で行うのか(Why)
    • だれのどういう課題を解決するのか、顧客はどういうものを求めているかなど
  • このプロジェクトでは何をするのか、どういう機能を作るのか(What)
  • 誰が関係者なのか、Whatに対してそれぞれ誰が担当するのか(Who)
  • このプロジェクトはどうなったら完了なのか(Where)
  • 締め切りはいつなのか(When)
    • 複数の締め切りがあるなら、どのタスクはどの締め切りに間に合わせないといけないのか
  • このプロジェクトをどうやって進めていくのか(How)
    • タスク管理はどうするのか、コミュニケーションはどのようなツールを用いるのか


この中で一番重要なのはWhy。なぜやるのかというのが明確になっていないと、何をするのかとか、どうなったら完了なのかとかが全て決まらない。

またHowは一番最後に決める。なぜやるのか、何をやるのか、誰が担当するのか、締め切りがいつなのかに従って、適したやり方が変わってくるためである。なのでこういう基本的なことが決まる前にいきなり開発フローとかどういうツールを使うかとかを話し合うのはあまり意味が無いと思っている。


この辺は大体プロジェクトのリーダーが簡単に文章化し、それを元にミーティングをおこなって質問を受けたり議論をしながら、チームの納得のいくものにしていくと良い。

個々の責任範囲を明確にする

5W1Hと並行して、プロジェクトを始めるときには必ず個々の責任範囲を明確にしておきたい。つまり、ある人がどこまでだったら自分の裁量で物事を決めても良いかを明確にしておきたい。

プロジェクトにプロダクトオーナー、スクラムマスター、エンジニア、デザイナーがいたとする。その場合例えば

  • プロダクトオーナーは要件の追加や変更を行える。その他の人はプロダクトオーナーと相談なしに追加できない
  • スクラムマスターは自分の裁量でチーム全体の開発フローに変更を加える事ができる。それ以外の人はスクラムマスターに一度相談する
  • エンジニアは自分の裁量で、エンジニアのみの開発フローに変更を加える事ができる
  • デザイナは自分の裁量で、担当しているページのデザインを決めることができる。ただし最終的に決まってから作る前にはプロダクトオーナーに確認を取って欲しい

のように裁量を明確にしておくという感じ。もちろんもうすこし厳密にするか、もうすこし曖昧にするかはプロジェクトの性質によって自由に決めたら良い。


これをおこなう理由としては

  • それぞれのメンバーが自分の判断で自律的に動きやすくする
    • 自律的に動きやすくなれば、個々の得意分野を発揮しながら良い物を作っていくことができる
  • 報告する必要のないことも含め、全てのことをプロダクトオーナーなどに報告してしまい、無駄なコミュニケーションになるということを防ぐ
  • 重要な事柄を報告されない、ということを防ぐ
  • 自分の裁量で決められるので、モチベーションが向上する
    • 人の決めたことをただやるだけだったら、モチベーションが湧かない
  • 仕事が分業化され、プロダクトオーナーが全てを見ないといけなくて仕事量が多すぎる、みたいなことが減る

などがある。


上からの命令に従ったプロダクトしか作れなくてモチベーションが湧かないとか、マネージャが忙しすぎて捕まえられないとか、部下が勝手に動きすぎるとか、そういうあるあるネタを防ぐことができるので、責任範囲を明確にしておくのはかなり大事だと思っている。

一つの場所にまとめておく

以上の二点をチームメンバーと共有して、チームメンバー全員の納得が得られたら、プロジェクトまとめとしてどこかに残しておくと良い。普通にA4の紙に書いておいても良いし、Google Docsを利用したり、Githubを利用したり、そのあたりは何を使っても良い。

ただし、気をつけたいことはプロジェクトを進めるごとに、Whenが変わったり、Howをさらに良くしたり、責任範囲の分割の仕方を間違えてたり、ということがあるので、出来る限り編集はしやすくしておいたほうが良さそう。

まとめ

けっこう開発フローの話が話題になるし僕もそういう話は好きなのだけど、自分でプロジェクトを実際に回してみるとそれに至る前に考えないといけないことがいろいろあると思ったのでまとめてみた。そうすると結局5W1Hを全部決めておくことが大事とか、責任範囲を定めておくことが大事とか当たり前のことをちゃんとするのが重要ということが分かってきて面白い。

なんとなく経験でまとめているだけなので、こういう考えもあるのではとか、こういう本読んだら良いとかあったら教えて下さい。

符号化文字集合と文字符号化方式 - 「プログラマのための文字コード技術入門」を読んだ

最近文字コード周りでハマった時に、文字コードというものをそもそもちゃんと分かってないと気づいた。そこで「プログラマのための文字コード技術入門」を読んで勉強してみた。

この本はコンピュータにおける文字について体系的にまとめてくれている。ASCIIやLatin1、UTF-8Unicodeについて、どういう分類で何のために使われているかを知ることができる。また、歴史も合わせて教えてくれるので、今現状起こっている問題(円マークとバックスラッシュ問題とか)がどういう経緯で起こってしまったのかなどを理解できる。

簡単な文章で書かれているので、一度でも文字コードに関係することでハマったことのある人なら、どんどん読めると思う。ただ、符号化文字集合文字符号化方式の違いについてわかった上で読んだほうが内容が理解しやすいと思う。

個人的な感想では、この本によって今まで漠然としか分かってなかったことが明確にできたので、とにかく良い本だった。過去になぜハマったのかとか、よく分からずに使っていたこととかを理解することが出来た。おすすめ。


この本の中で、自分は以下の二つが特に勉強になったのでまとめてみる。

符号化文字集合文字符号化方式

これまで自分はコンピュータの中の文字というものを、「文字コード」という一つの概念として捉えてしまっていた。しかし、実際には符号化文字集合文字符号化方式という二つの概念が存在し、これらが組み合わさってコンピュータの文字というものを表しているということを知った。

符号化文字集合

まず符号化文字集合について。文字を表現するためには、まずは文字の集合が必要である。またコンピュータでそれを表すためには、それぞれの文字に一意な番号をふって置く必要がある。例えば、スペースなら32番、「a」なら97番という感じ。番号をふっておけば、その番号に従って、ディスプレイ上に文字を表示することができる。この番号のことを、便宜的にこの記事では「コードポイント」と呼ぶ。

JIS X 0201-1997規格票によると、符号化文字集合の定義としては以下のとおり。

符号化文字集合、符号文字集合を定め、かつ、その集合内の文字とビット組合せとを1対1に対応づける、あいまいでない規則の集合。

ASCIIやJIS、Unicodeなどは符号化文字集合である。

文字符号化方式

次に文字符号化方式について。文字符号化方式は、複数の符号化文字集合を組み合わせる、過去への互換性を保つ、などといった要件を達成するための運用方式のこと。符号化文字集合を運用しやすいように別のバイト列に変換する方式のことである。

EUC-JPや、Shift_JISUTF-8UTF-16などは文字符号化方式である。例えばJIS系の文字集合を符号化する方法がEUC-JPやShift_JISであり、Unicode文字集合を符号化する方法がUTF-8UTF-16である。

符号化文字集合文字符号化方式の関係

符号化文字集合文字符号化方式の関係は図にしてみると分かりやすい。イメージ図のため少し正確さにはかけるが、こういうイメージ。

f:id:shiba_yu36:20150913141538j:plain:h500

上のように「あ」を例にしてみる。「あ」はUnicodeのコードポイントでは「U+3042」である。これをUTF-8で符号化した場合、「0xE3 0x81 0x82」というバイト列になる。これをUTF-16で符号化した場合は、バイト列はUTF-8と違い、「0x30 0x42」となる。

JISとEUC-JPもこのような関係になっている。Unicodeは世界中の文字を一つの文字集合にまとめるという思想なので、文字集合は一つになっている。EUC-JPの場合はASCIIとJIS X 0208JIS X 0201JIS X 0212の4つを文字集合を扱うので、この切替もEUC-JPという符号化方式によってなされている。

なぜ自分が混同してしまったか

自分は符号化文字集合文字符号化方式を混同して、「文字コード」という概念として考えてしまっていた。なぜこうなってしまったのか考えてみることで、もうすこし文字について理解を深めてみたい。


考えてみたところ、それはASCII、Latin1、UCS-2の存在があるからなのではないかと思った。

ASCIIの時代は文字集合が128個以下に収まっていたため、コードポイントは7bitまでで収まっていた。そこで1バイト単位で考えて、何も変換せずともそのコードポイントのまま扱ってしまえば、問題なかった。Latin1の場合も文字集合は256個以下に収まっていたので、そのコードポイントのまま扱ってしまえばよかった。つまりそのころは文字符号化方式という変換方式は必要なかった。

ASCIIやLatin1はコードポイントと符号した後のバイトが一致しているので、現在でいうところの符号化文字集合文字符号化方式の両方の役割をまとめておこなっているように見える。

このことや文字コードを指定する際にLatin1とEUC-JP、UTF-8を選べることから、自分の中ではASCII、Latin1、EUC-JPUTF-8ASCIIもLatin1もUTF-8も同じように考えてしまって、すべて混同してしまっていたのではないかと思う。


ちなみに、ASCIIやLatin1で保存されたファイルが、コードポイントと一致しているかは、以下のコマンドで出力される16進数が、https://ja.wikipedia.org/wiki/ASCIIhttps://ja.wikipedia.org/wiki/ISO/IEC_8859-1 に書いてあるコードポイントと一致しているかを見れば分かる。

$ od -c -t x1 text-ascii-containing-only-ascii.txt
$ od -c -t x1 text-latin1-containing-all-latin1-characters.txt

https://github.com/shibayu36/char-encoding-study この辺に適当にファイルとかは置いておいた。

ある文字符号化方式がASCIIに互換しているとは

たまに、「ASCII互換の場合は」という言葉を見かけることがある。自分はこれについてよく分かってなかったのだけど、この本を読んで理解することが出来た。

自分の理解では、ある文字符号化方式がASCIIに互換しているとは、「ASCIIで保存されたASCIIの文字集合のみで構築された文章をその文字符号化方式で読み込んだ時に、同じ文章を表示できるか」、である。


例えば「aiueo」という文字列について考えてみる。「aiueo」はASCIIで保存されると「0x61 0x69 0x75 0x65 0x6f」というバイト列として保存される。この「aiueo」をUTF-8で保存すると、同様に「0x61 0x69 0x75 0x65 0x6f」として保存される。

このようにASCIIとUTF-8はASCII文字集合の文字列を同じバイト列で保存しているため、ASCIIで保存された文章をUTF-8で読み込んだ時に同じ文章を表示できる。よってUTF-8はASCIIに互換している。

UTF-16の場合は「aiueo」は「0x00 0x61 0x00 0x69 0x00 0x75 0x00 0x65 0x00 0x6f」というバイト列になる。そのためASCIIで保存された「0x61 0x69 0x75 0x65 0x6f」というバイト列をUTF-16で読み込んでも、「aiueo」とは解釈できないため、UTF-16はASCIIに互換していない。


昔に書かれたプログラムなどはASCIIで書かれている。これとの互換性を持たせないと古い資産を一度今の文字コードに変換してからでないと利用することが出来ない。UTF-8の場合、ASCIIに互換しているため、古いプログラムもそのまま利用できる。これがUTF-8が今一般的になっている理由の一つかなと思った。

まとめ

プログラマのための文字コード技術入門」は、これまで「文字コード」という概念としてなんとなく知っていたものを明確にしてくれる本で非常に良かった。一度でも「文字コード」周りでハマったことがあるなら読んでみると良さそう。

他にも以下のようなURLが参考になった。