Your Knowledge Portfolio【The Pragmatic Programmer】
知識ポートフォリオを構築して適切に管理しよう。 知識ポートフォリオは投資におけるポートフォリオと同じような視点で管理するとよい。各アイテムの間でバランスを取り、リスクの高いアイテムと低いアイテムを組み合わせよう。
ただし、もっとも重要なのは定期的に投資することだ。 定期的に知識に投資することが成功の秘訣だ。
具体的なアクションの一例を挙げる。
- 一年に一つ、新しい言語を学ぶ
- 本を読む。そして、それを習慣付ける
- 勉強会に参加し、ネットワーキングする
- 知識を常に最新に保つ
書籍や Web から得た知識を批判的に考察することも重要だ。 商業主義を甘く見てはいけない。
検索で上位に来るページが、必ずしも正しいとは限らないのだから。
Diversity
この本では、知識ポートフォリオにおける多様性の重要性を説いている。一方、Soft Skills では業界の専門性の重要性を説いていた。
業界の専門性を重視した方が自分をマーケティングしやすいからだ。
「Web の EC からエンタープライズまで手広く 10 年間やってました。」
というエンジニアよりも、
「不動産の法律業に関する IT 部門で 10 年開発してました。」
というエンジニアの方が自分をマーケティングしやすいでしょう、というのがその理由。
専門性を高めると需要は少なくなる一方、自分の価値は高まる。
専門化によって機会を失うことは増えるだろう。しかし、専門性を高めることでしか得られないチャンスが多くあるし、チャンスをものにできる確率が増える、とのこと。
自分は技術の多様性はある方だと思うが、業界の専門性が皆無なのでここはどうにかしないといけないと感じている…。
言語を学ぶ
一年に一度言語を学ぶことはとてもいいことだと思う。でも、同じような言語を学んでいると「学習」という観点からだと効果が少ないように思える。せっかくだから Go とか Swift ばかり触ってないで Prolog とかを触ってみるのがいいと思う。あと、「触ってみましたー」程度だと「何か新しい事をしている」という楽しみは得られる反面、技術的にはあまり得るものがないように思える時もある。
でも、『定期的に』新しいものを触る癖をつけるということがきっと重要で、ぐだぐだ言い訳せずに定期的に新しいものを触る癖をつけるべきだなぁ、と反省した。
Good-Enough Software【The Pragmatic Programmer】
完璧でバグのないソフトウェアはありえない。
だからといって悲観する必要はない。 ユーザーにとって、経営者にとって、そして私たちの心の平穏にとって、充分なクオリティというものが存在する。完璧でなくても充分よければそれでいい。
ユーザーは明日の完璧なソフトウェアよりも今日動く充分よいソフトウェアを欲している。 プログラマはいつプログラミングを終えるべきか常に考えなければならない。 充分よいソフトウェアを、今日ユーザーに提供しよう。
どうせ完璧なソフトウェアは存在しないのだから。
完璧を目指すのは悪か。
「明日の完璧なソフトウェアより、今日動くソフトウェアがほしい。」
この発想はこの本が書かれた当時よりも一般化していると思う。むしろ最近では『明日の充分よいソフトウェアよりも、今日の動くソフトウェア』を提供することが増えているように思える(根拠はない)。
完璧なソフトウェアを目指すこと自体は悪いことではないと思う。完璧を目指していれば、いつの間にか充分よいものになっていることが多い。とりあえず動くものを作っておけばよいというメンタリティで充分よいものはできない、と僕は思う。
ただ、この本が述べているように、「完璧なものになるまでリリースしない」という姿勢は良くない。常に完璧なものを目指しつつ、現実(納期や技術力)に負けて筆を置き、ユーザーの審判を受ける。というのが一番 Pragmatic な姿勢なのではないかと思った。
Stone Soup and Boiled Frogs【The Pragmatic Prigrammer】
石のスープ
戦争から帰ってきた兵士が村に帰ってきた。しかし、彼らは食料を恵んでもらえない。そこで彼らは湧いたお湯に石を入れ『あとは人参があれば美味しいスープができるのになぁ』とつぶやく。すると村人たちが興味を持ち、人参だけでなく様々な食材を持ち寄ってくれる。
最終的に兵士たちは石を取り除いて美味しいスープを食べました。めでたしめでたし。
この話が暗示するのは「何か面白いことの片鱗さえ見せることさえできれば車輪が回り始める」というものだ。すべてを自分で作り、見せる必要はない。自分が触媒(Catalyst)となり、周りを刺激しようという話。
茹でガエル
一方、触媒となるために一つのことに集中しすぎると痛い目にあう。熱いお湯にカエルを入れるとすぐに気づいて逃すだろう。しかし、ぬるいお湯からどんどん温度を上げていくと当のカエルは気づかない。気づいた時にはすでに遅し。茹でガエルの出来上がり。
常に周りに気をかけていないと環境が悪化してることに気づかない。割れ窓理論と違うのは『本人がそれに気づいているか』ということ。割れ窓理論は『よくない環境があると気付きながら、それが普通になり誰も気にしなくなる』という話。一方、茹でガエルの話では気づかぬ間に自分は死んでいる。
この話は結構示唆に富んでいるなぁと思う。自分は茹でガエルなのかも…とドキッとしてしまった。
『自分のしていることだけでなく周りを見渡そう』
はい。気をつけます…。
Software Entropy【The Pragmatic Programmer】
二つ目は "Software Entropy"。
割れ窓理論
ソフトウェアは物理世界とは隔離されているが、エントロピー増大の法則からは逃げられない。 どんなに素晴らしいソフトウェアであっても時間と共に朽ちていく。こういう状況を錆びに例えて "Software Rot" というようだ。
これを防ぐため『割れ窓理論』を応用しようと書かれている。割れ窓理論とは次のようなものである。
割れ窓理論(われまどりろん、英: Broken Windows Theory)とは、軽微な犯罪も徹底的に取り締まることで、凶悪犯罪を含めた犯罪を抑止できるとする環境犯罪学上の理論。アメリカの犯罪学者ジョージ・ケリングが考案した。「建物の窓が壊れているのを放置すると、誰も注意を払っていないという象徴になり、やがて他の窓もまもなく全て壊される」との考え方からこの名がある。 (https://ja.m.wikipedia.org/wiki/割れ窓理論)
窓が一つでも割れていると、加速度的に環境が悪化していく。 一方、綺麗に装飾された家が建ち並んでいれば環境は悪化しない。
これをソフトウェアに応用しようという話だ。 割れ窓のようなコードが一つでもあると「ここもそうしてるしいいだろう」と思ってしまう。 一方、綺麗に整理されたコードではそういうことは起こらない。 「汚す」という行為に対して心理的な抵抗が現れる。
ソフトウェアの品質
ソフトウェアの割れ窓を見つけることはそれほど難しくない。 プログラマならば担当してるソフトウェアのイケてない点をいくらでも挙げられるだろう。 きっとそれが割れ窓だ。 クラス構成がいけてない。語彙が統一されていない。ビルドシステムが古い。
しかし、割れ窓やサビに注目しすぎるもどうだろう、と思うことがある。 割れ窓理論はソフトウェアの品質に寄与すると思うけれど、「ソフトウェアの品質」とはユーザーにとっての価値がベースである、とどこかで読んだ気がする(『テストから見えてくるグーグルのソフトウェア開発』だったかな?) 割れ窓に注目しすぎて、ユーザーを置いてけぼりにしないように注意したい。
- 作者: ジェームズ A ウィテカー;ジェーソンアーボン;ジェフキャローロ
- 出版社/メーカー: 日経BP社
- 発売日: 2014/02/12
- メディア: Kindle版
- この商品を含むブログ (8件) を見る
The Cat Ate My Source Code【The Pragmatic Programmer】
明けましておめでとうございます。 2017年もすでに10日ほど経過してますが…。
一年半くらい書いてきた Effective Java シリーズが終わってしまって、イマイチ継続的にブログを書く感じにならない。 やっぱり、何かをシリーズ化してノルマにすることがブログを継続するコツですね。習慣付いてるとシリーズ以外のネタを書くことへの心理的障壁も下がるし。
The Pragmatic Programmer
以前から The Pragmatic Programmer は一度読んでみたいと思っていた。ちょうど rebuild で話題になってたし、これを読んで1章ずつまとめてみようと思う。rebuild では「古い部分が多い」という話だったので、なるべく「今ならどーするか」みたいな話を入れていきたい。
The Pragmatic Programmer は日本語版が pdf で読めるようになってるんだけど、残念ながら Kindle にはなかった。今回は、英語の勉強も兼ね原著を読もうと思う。(しかし、Kindleで4000円は高いと感じてしまうな…)
The Pragmatic Programmer: From Journeyman to Master
- 作者: Andrew Hunt,David Thomas
- 出版社/メーカー: Addison-Wesley Professional
- 発売日: 1999/10/20
- メディア: ペーパーバック
- 購入: 1人 クリック: 18回
- この商品を含むブログ (7件) を見る
The Cat Ate My Source Code
1章は Take Responsibility について述べてる。簡単にまとめると、
- Take Responsibility しろ
- 失敗と無知を認めることを恐れるな
- クソな言い訳をするな
- 失敗した時のために対案をもっておけ
- 無理なら断れ
というところか。言ってることは至極真っ当である。うんうん、そうだよね。誠実さ。大事だよね。
でも、ここにたどり着くために実践するべき日々の行動をもう少し書いてくれれば、と感じた。あるべき姿だけ書かれていると大抵の人が「うんうん、そうだよね。誠実さ。大事だよね。」で終わってしまうわけだ。たとえば、「アクション:明日から自分のミスを毎日一つ書いて同僚と共有してみよう!」のように書いてあると少し違うのではないか。
こういう点は『Soft Skills』の方が手厚い印象を受ける(同じく『情熱プログラマ』も)。『Soft Skills』だと、"Chapter 10. Being a professional" でまさに同じことが書かれているし、取るべきアクションについても書かれているし。
- 作者: ジョン・ソンメズ,まつもとゆきひろ(解説),長尾高弘
- 出版社/メーカー: 日経BP社
- 発売日: 2016/05/20
- メディア: 単行本
- この商品を含むブログ (5件) を見る
- 作者: Chad Fowler,でびあんぐる
- 出版社/メーカー: オーム社
- 発売日: 2010/02/26
- メディア: 単行本(ソフトカバー)
- 購入: 24人 クリック: 683回
- この商品を含むブログ (126件) を見る
もちろん、『Soft Skills』や『情熱プログラマ』は The Pragmatic Programmer に多くの影響を受けている、と明確に書かれているので、元ネタを基にしてさらによい方法で書かれているのは当然なのだろうけれど。
そして、まだ一つしか読んでないのでこう判断するのは早いのかもしれない。もしかしたらこの後に出てくるのかもしれないし。
次章は "Software Entropy"。
見積もりのずれ
最近、見積もりをしてから仕事に取り掛かるようにしている。プロのソフトウェアエンジニアとして見積もり能力は重要だと思う(たぶん)。「それ、簡単にできますよ(どやぁ」と放言して、できたのは半年後なんてのはプロとはいえない。
ちゃんと見積もって実績を評価してみたら、見積もりのずれは作業の遅れではなく、作業時間の不足から起こりがちだなと気づいたというお話。
見積もりの仕方
自分は次のように見積もりをする。
- 直感で全体の見積もり:「まあ、この機能なら1ヶ月くらいで出せるでしょ」
- 作業項目への分割:「作業的には、既存実装の調査、モデル側実装、ビュー側実装、テスト、バグ修正、リリース作業、かな。」
- 時間単位で見積もり:「これは2時間くらい、これは6時間くらい、あーこれは重そうだから16時間くらいかかりそう…」
- 足し算:「全部で120時間か…」
- 遅延係数1.5をかける:「1.5 をかけると180時間か…1ヶ月じゃおわんねーな」
脇道にそれるが、何を持って「作業終了」とするかは事前にマネジメント側と認識をあわせておくべき。しかし、「自分の作業物に一切手を加えないでプロダクション環境にリリースできる状況」を作業終了としておけばほとんどの場合でマネジメント側と認識がずれることはない。すなわち、設計、実装、コードレビュー、再修正、テスト、テストバグ修正、リリース準備とリリース、をすべて作業に含んでおく。
遅延係数
ほとんどのソフトウエアエンジニアは楽観的で自分の能力を過大評価し、作業の難易度を甘く見る。例に漏れず自分も楽観的である。「金曜までに終わるな」と思った作業は、大抵、次の週の半ばにリリースされる(or マージされる)。さすがに5年くらい仕事してると、こういう自分の性質を理解しているので、最終的な見積もりを出す時には直感の値に係数1.5をかける。
ちなみに 1.5 をかけると自分の直感と比較してだいぶスケジュールが伸びることになる。直感と反するので不安になる。こんなにも時間がかかるなんて無能だと評価されないだろうか…。しかし、仕事は信頼感の方が大事。見積もりには不安を抑える力も必要だ。
仕事は早いに越したことはない。しかし、できると言った期間にできてないのは困る。もし、早く終わらせたいのであれば、作業量を調整するかより腕の立つエンジニアを連れて来てもらうしかない。これはマネジメント層の問題であり、ソフトウェアエンジニア個人にはどうしようもない。
遅延係数の正体
さて、ようやく本題。
この遅延係数 1.5 の正体は何だろうか。この 1.5 は自分の能力の過信率だと考えていた。すなわち、自分は自分の能力を 1.5 倍過信している。直感による見積もりでは、作業をその分だけ過小評価している。と。
しかし、そうではなかった。
自分の作業にはポモドーロを導入している。これによって明確に集中した作業時間を計測することができるようになった。週のポモドーロ総数は大抵 40〜45 だ。調子のいい日は 12 程度確保できるが、調子が悪かったり打ち合わせが入ると 5〜6 だったりする。
この実績ポモドーロ数と作業見積もりの値を比較すると、実は見積もりの値は正確であることがわかった。すなわち、5〜6 時間を見積もったタスクは 10 ポモドーロ程度かかっている。ということは、この遅延係数は自分の作業自体の遅延ではない。
実は、見積もった値を日にちに変換する際に問題があった。8 時間勤務で、オーバーヘッド含めても7時間程度は作業できると考え、7時間で一日に変換していた。しかし、7時間の作業といえば14ポモドーロである。こんなにも集中して作業するのはほぼ無理だ。実測は平均で8~9である。実際、4~5時間がいい線である。
これが遅延係数の正体だ。
まとめ
結局のところ、ちゃんと集中して作業する時間を確保することこそが、遅延を回避する一番の方法だということだ(自分にとってね)
【Effective Java】各項目のまとめ
Effective Java シリーズの各項目の一覧。
第1章:はじめに
第2章:オブジェクトの生成と消滅
- 項目1:コンストラクタの代わりに static ファクトリーメソッドを検討する
- 項目2:数多くのコンストラクタパラメータに直面した時にはビルダーを検討する
- 項目3:private のコンストラクタか enum 型でシングルトン特性を強制する
- 項目4:private のコンストラクタでインスタンス化不可能を強制する
- 項目5:不必要なオブジェクトの生成を避ける
- 項目6:廃れたオブジェクト参照を取り除く
- 項目7:ファイナライザを避ける
第3章:すべてのオブジェクトに共通のメソッド
- 項目8:equals をオーバーライドするときは一般契約に従う
- 項目9:equals をオーバーライドする時は、常に hashCode をオーバーライドする
- 項目10:toString を常にオーバーライドする
- 項目11:clone を注意してオーバーライドする
- 項目12:Comparable の実装を検討する
第4章:クラスとインタフェース
- 項目13:クラスとメンバーへのアクセス可能性を最小限にする
- 項目14:public のクラスでは、public のフィールドではなく、アクセッサーメソッドを使う
- 項目15:可変性を最小限にする
- 項目16:継承よりコンポジションを選ぶ
- 項目17:継承のための設計および文書化する、でなければ継承を禁止する
- 項目18:抽象クラスよりインタフェースを選ぶ
- 項目19:型を定義するためだけにインタフェースを利用する
- 項目20:タグ付クラスよりクラス階層を選ぶ
- 項目21:戦略を表現するために関数オブジェクトを利用する
- 項目22:非 static のメンバークラスより static のメンバークラスを選ぶ
第5章:ジェネリックス
- 項目23:新たなコードで原型を使用しない
- 項目24:無検査警告を取り除く
- 項目25:配列よりリストを選ぶ
- 項目26:ジェネリック型を使用する
- 項目27:ジェネリックメソッドを利用する
- 項目28:API の柔軟性向上のために境界ワイルドカードを使用する(その1)
- 項目28:API の柔軟性向上のために境界ワイルドカードを使用する(その2)
- 項目29:型安全な異種コンテナーを検討する
(以下、ジェネリックスの補足記事)
第6章:enum とアノテーション
- 項目30:int 定数の代わりに enum を使用する
- 項目31:序数の代わりにインスタンスフィールドを利用する
- 項目32:ビットフィールドの代わりに EnumSet を使用する
- 項目33:序数インデックスの代わりに EnumMap を使用する
- 項目34:拡張可能な enum をインタフェースで模倣する
- 項目35:命名パターンよりアノテーションを選ぶ
- 項目36:常に Override アノテーションを利用する
- 項目37:型を定義するためにマーカーインタフェースを使用する
第7章:メソッド
- 項目38:パラメータの正当性を検査する
- 項目39:必要な場合は、防御的にコピーする
- 項目40:メソッドのシグニチャを注意深く設計する
- 項目41:オーバーロードを注意して利用する
- 項目42:可変長引数を注意して使用する
- 項目43:null ではなく空配列か空コレクションを返す
- 項目44:すべての公開 API 要素に対してドキュメントコメントを書く
第8章:プログラミング一般
- 項目45:ローカル変数のスコープを最小限にする
- 項目46:従来の for ループより for-each を選ぶ
- 項目47:ライブラリーを知り、ライブラリーを使う
- 項目48:正確な答えが必要ならば、float と double を避ける
- 項目49:ボクシングされた基本データより基本データを選ぶ
- 項目50:他の型が適切な場所では、文字列を避ける
- 項目51:文字列結合のパフォーマンスに用心する
- 項目52:インタフェースでオブジェクトを参照する
- 項目53:リフレクションよりインタフェースを選ぶ
- 項目54:ネイティブメソッドを注意して使用する
- 項目55:注意して最適化する
- 項目56:一般的に受け入れられている命名規約を守る
第9章:例外
- 項目57:例外的状態にだけ例外を使用する
- 項目58:回復可能な状態にはチェックされる例外を、プログラミングエラーには実行時例外を使用する
- 項目59:チェックされる例外を不必要に使用するのを避ける
- 項目60:標準例外を使用する
- 項目61:抽象概念に適した例外をスローする
- 項目62:各メソッドがスローするすべての例外を文書化する
- 項目63:詳細メッセージにエラー記録情報を含める
- 項目64:エラーアトミック性につとめる
- 項目65:例外を無視しない
第10章:平行性
- 項目66:共有された可変データへのアクセスを同期する(前半)
- 項目66:共有された可変データへのアクセスを同期する(後半)
- 項目67:過剰な同期は避ける
- 項目68:スレッドよりエグゼキューターとタスクを選ぶ
- 項目69:wait と notify よりコンカレンシーユティリティを選ぶ(前半)
- 項目69:wait と notify よりコンカレンシーユティリティを選ぶ(後半)
- 項目70:スレッド安全性を文書化する
- 項目71:遅延初期化を注意して使用する
- 項目72:スレッドスケジューラに依存しない
- 項目73:スレッドグループを避ける
第11章:シリアライズ
- 項目74:Serializable を注意して実装する
- 項目75:カスタムシリアライズ形式の使用を検討する(前半)
- 項目75:カスタムシリアライズ形式の使用を検討する(後半)
- 項目76:防御的に readObject を書く
- 項目77:インスタンス制御に対しては、readResolve より enum 型を選ぶ
- 項目78:シリアライズされたインスタンスの代わりに、シリアライズ・プロキシを検討する
EFFECTIVE JAVA 第2版 (The Java Series)
- 作者: Joshua Bloch,柴田芳樹
- 出版社/メーカー: 丸善出版
- 発売日: 2014/03/11
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (11件) を見る
Kindle 版はこちら(ただし英語)
Effective Java: A Programming Language Guide (Java Series)
- 作者: Joshua Bloch
- 出版社/メーカー: Addison-Wesley Professional
- 発売日: 2008/05/08
- メディア: Kindle版
- この商品を含むブログを見る