30歳からのプログラミング

30歳無職から独学でプログラミングを開始した人間の記録。

『Joel on Software』を読んだ

Microsoft での勤務経験を持ち Stack Overflow の創業者でもある Joel Spolsky によるエッセイ集。

Joel は自身が運営するウェブサイト Joel on Software で多数の記事を公開しており、その一部を掲載したのが本書。

ひとつひとつの章がかなり短い(長いものでも 20 ページくらい、短いものだと 4 ページほど)ので気軽に読めるし、各章は独立しているので興味のある部分だけ読むこともできる。

技術そのものについて解説している技術書ではなく、ソフトウェア開発やソフトウェア産業についての著者の考えが書かれており、 Paul Graham の『ハッカーと画家』にテイストが近いかもしれない。
無料で公開されているエッセイ集をまとめたもの、というのも『ハッカーと画家』に似ている。

本書に収録されているのは 2000 年から 2004 年に書かれた記事なので、さすがに古さを感じるものもある。
未来予測のような内容も含まれるので、現在の視点から「答え合わせ」してみるのも面白いかもしれない。

以下、特に面白かった章の要約。

  • 第 20 章 採用面接ゲリラガイド

    • 候補者は、明らかに水準に到達していない人、何とも言えない人、スーパースターの 3 種類いる
      • 何とも言えない人とスーパースターを区別して前者を採用しないことが重要
    • 特定のタスクを非常によくこなせるとしても、他のチームではあまり上手くいかないような候補者も不採用
      • 変化の速い世界なので、どのようなタスクでもこなせる人間が必要
    • 分からない、境界線上だ、というケースは全て不採用
      • どっちつかずの候補者はすべて機械的に不採用にする
    • なぜなら、まずい候補者を採用するよりは、いい候補者を落とすほうがずっとマシだから
    • 優れた候補者を見つけるのがいかに難しく感じられても、基準を下げてはいけない
    • 採用するべきなのは、頭がよくて物事を成し遂げる人
    • 頭のよさを見分けるために、候補者の頭のよさを示せるような状況を作ることが重要
      • 自分の話ばかりして候補者に話す時間を与えない面接官はダメ
      • 頭のよさを「たくさんの事実を知っていること」だと思ってクイズショーを展開する面接官もダメ
    • ソフトウェアチームが採用するべきなのは、特定のスキルセットを持っている人ではなく、資質を持っている人
      • スキルセットはすぐ陳腐化するのだから、どんな新技術でも学べる人を雇ったほうがいい
    • その人を知るための一番の方法は、その人に話をさせること
      • そのために自由回答式の質問と問題を与える
    • 面接する候補者の情報はできるだけ入れないようにする
      • どうしてもバイアスが掛かってしまうから
  • 第 24 章 あなたが絶対すべきでないこと PART I

    • プログラムをスクラッチで書き直すのは、最悪の戦略的誤り
    • プログラマが既存のコードを捨てたいと思いがちなのは、プログラムは書くより読むほうが難しいため
    • しかし、古いコードは様々な面で新しいコードよりも利点がある
      • 古いコードは既に動いている
      • 古いコードは歴史のなかでテストされている
        • 多くのバグが見つかり、それが修正されている
        • 実世界のなかで何週間も使われたからこそバグが見つかった
    • コードを捨てることは積み重ねられたバグフィックスを捨てることを意味する
  • 第 26 章 漏れのある抽象化の法則

    • 抽象化とは、複雑なことが行われている中身を隠して単純化すること
    • 抽象化によって、中身の詳細を知らなくても利用できるようになる
    • 例えば TCP は IP の上に構築されているが、抽象化によって IP のことを意識することなく TCP を利用できる
    • しかし TCP より下層の部分で何か問題が発生すると、 TCP は機能しなくなる
      • 何からの理由で IP パケットが全く届かなくなったり、ネットワークケーブルが切断されてしまったり
    • このような状態を Joel は「漏れのある抽象化」と呼んでいる
    • 自明ではない抽象化はすべて、多かれ少なかれ漏れがある
    • 普段は上手くいっていても、時折漏れ出してきて、問題が発生する
      • メモリの仕組みを知らなくても問題なくコードを書けるかもしれないが、知っていないことで、ものすごくパフォーマンスに問題のあるコードを書いてしまうかもしれない
        • コンピュータの仕組みを完全に抽象化することはできず、このように漏れ出してくることがある
      • SQL のクエリでも似たようなことが起こり得る
    • 抽象化によって隠されている「下層」について知らないと、抽象化に失敗して下層が漏れ出してきたときに対応できない
  • 第 33 章 ビッグマック 対 裸のシェフ

    • 物事を上手くやるためには才能が必要
    • だが才能をスケールさせるのは困難
    • そこで、才能ある者がルールを作り、凡庸な人間がそれに従うというやり方で、スケールさせようとする
    • しかしその結果として得られる成果物の品質は低い
      • 一定であり安定しているかもしれないが、低い
    • ルールや手順は、平時においては上手く機能するかもしれない
      • だが状況の変化に対応できない
      • ルールを作った才能ある人達なら、対応できるだろう。だがルールに従うしかできない人間では、対応できない。対応できるだけの能力がないからこそ、ルールを必要としそれに従っているわけだから。
    • これが、企業の勃興と衰退が繰り返される理由
      • 硬直化し時代に対応できない大企業を、若い才能が追い抜く。しかし才能はスケールしない。そこで才能ある者がルールを作り、凡庸な人間にそれに従わせる。最初は上手くいくが、状況変化に対応できず勢いを失っていく。
    • この過ちを犯さないためには、優秀な人間を雇うことに執着しなければならない

Unicode における置換文字(replacement character)について

この記事では、 Unicode において表示不可能な文字を表現する「置換文字」について説明する。

この記事に出てくるコードの動作確認は以下の環境で行った。

  • Deno 1.26.0
  • TypeScript 4.8.3

概要

Unicode において、表示しようとした文字が何らかの理由で表示不可能なとき、黒い菱形に白いクエスチョンマークが書かれた文字が表示される。
「�」がそうなのだが、環境によっては表示されずカギカッコの中が空白になっているかもしれないので、画像も載せておく。

この文字を「置換文字」と呼ぶ。

サロゲートペアとして不正なケース

文字が表示不可能な例として、サロゲートペアとして正しくないケースがある。

サロゲートペアや Code Point の概要は以前書いたので、必要ならこちらを読んで欲しい。
numb86-tech.hatenablog.com

Code Point のうち一部分はサロゲートペアに使うものとして予め定められており、単独で文字を表現することはない。
具体的にはU+D800からのU+DFFFの 2048 文字分がそれに該当する。
これらの Code Point は代用符号位置と呼ばれる。
さらに、代用符号位置は前半(U+D800U+DBFF)と後半(U+DC00U+DFFF)に分かれており、前半を上位サロゲート、後半を下位サロゲートとして使うことも決まっている。

上記のルールに反した場合、無効なデータと見做され置換文字が表示される。

// 単独の代用符号位置で文字を表現することはできない
console.log(`\u{d800}`); // �

// dc00 が上位サロゲートに来ることはないし、 d800 が下位サロゲートに来ることもない
console.log(`\udc00\ud800`); // ��

置換文字の Code Point や Code Unit について

表示不可能な文字は全てとして表示しようというだけの話なので、表示結果が同じだったとしても、 Code Point や Code Unit が異なれば、それは別の文字である。

const x = `\udc00`;
const y = `\udc01`;
const z = `\udc02`;

// 三文字とも � と表示されるが……
console.log(x, y, z); // � � �

// 全て別々の文字である
console.log(x === y); // false
console.log(x === z); // false
console.log(y === z); // false

ちなみに、そのものの Code Point はU+FFFDである。

console.log("�".codePointAt(0)?.toString(16)); // fffd