「新装版 達人プログラマー 職人から名匠への道」が2016年に出版されているが、
2000年に出版された初版をお家時間が増えたので今一度振り返ってみたい。
20年前の情報が今でも役立つならば、これから先の20年もきっと役立つ可能性が高いだろう。
本書では70のヒントが掲載されている。
その中から役立ちそうなヒントや疑わしいアドバイスをピックアップしてみた。
その前に、元シリコンバレーのエンジニアのプログラミング歴を振り返ってみる。
プログラミング歴
職業プログラマーでないひとがこの本の善し悪しを語るのは原則NGだ。なぜなら、未経験者の意見など誰も求めていないからだ。
プログラミングを2〜3年やっただけでは分からない奥の深い世界だ。
はじめてプログラミングは、今から30年以上前のポケコンがきっかけだった。
ポケコンとは、その名の通りポケットに入るぐらいの小型コンピュータ。
1980年代の後半、当時小学2~3年生ぐらいのとき我が家にカシオのポケコンがやってきた。
「何これ!すごい!」と衝撃を受けた記憶が今でもある。
液晶は、電卓よりちょっと大きい程度。
しかし、明らかにコンピュータと認識できる代物でだった。
プログラミングの入門用に適したBASIC搭載。これが、はじまりだ。
その後、小学校4~5年生ぐらいのとき兄が欲しがっていたMSX2+が我が家に。
はじめはベーマガと呼ばれる月刊の「マイコンBASICマガジン」に掲載された読者投稿のプログラムを自分のパソコンに入力しては、エラーで動かない原因を探す日々だった。
だんだんとコツをつかむと、自分でもゲームを作って遊ぶのが日課になった。
1990年代には、NECのPC-9801 DAを両親からクリスマスプレゼントにもらい、さらにプログラミングにのめり込むことに。20数万のプレゼントなので、普通に考えるとちょっとどうかしている。
当時MS-DOSというディスクオペレーティングシステムと出会い、BASICでゲームを作ったり、楽譜からMIDI規格に則って音楽も作成したりした。
1990年代後半は、米国の大学でコンピュータサイエンスを専攻していた関係で、Windows、Solaris、Linux上で次のような言語も習得できた。
- C/C++言語
- アセンブリ言語
- Java
卒業後は、米国や日本のIT企業でプログラマーとして、PHP/Perl/Java/C/Bash/Pythonも使ってプログラミングしていた。
今でも役立つヒント(10)
あなたの作品に署名すること
我々は所有することによって誇りを持つべきなのだ。名前を入れることで「私はこれを記述した、そしてこの仕事の後ろには私が付いている」と。
品質の証明として、あなたの署名が入っているべきなのだ。
匿名性がだらしなさ、誤り、無精、まずいコードの温床となる。
特にプロジェクトが大規模になると、それが顕著に現れてくる。
Twitterでも匿名だと、あまり考えずに投稿することがよくある。
DRY – Don’t Repeat Yourself (繰り返しをさけること)
DRY原則を破ることは、同じ知識を2ヶ所以上に記述することだ。
この場合、片方を変更するのであれば、もう片方も変更しなければならない。
面倒だ。
これはあなたがおぼえていられるかどうかという問題なのではない。
あなたが忘れてしまった時の問題なのだ。
再利用されやすいようにしておくこと
「Don’t reinvent the wheel. 」と昔から言われている。
誰かがすでに生み出した何かを自分で生み出そうとして時間を無駄にしてはいけない。
プログラミングの世界では、過去に優秀なプログラマが膨大な量のコードを書いてきた歴史があり、ライブラリとして蓄積され、多くが公開されている。
したがって、プログラムを書く時でも、わざわざゼロから書く必要は無いわけだ。
先人が残したライブラリを利用すればかなり少ない時間や労力でうまく動作するプログラムを完成させることができる。利用できるものは感謝して利用しよう。
そして、コピーレフトについても知っておくべきだ。
著作権を保持したまま、二次的著作物も含めて、すべての者が著作物を利用・再配布・改変できなければならないという考え方は、必ず理解しておくべきだ。
つまり、後の事も考えて、はじめから再利用しやすいコードが記述することが望ましい。
あとでびっくりしないために、見積もりを行うこと
緊急事態宣言を延長するように、ずるずるとプロジェクトの延長を好む企業も存在する。
それは、Time and Material契約を顧客と結んでいる場合だ。
「現状は大変厳しい。5月7日のGo-Liveは困難と考える」と言って、延長したとする。
Time and Material契約した場合、かかった時間をかけ合わせた額を支払う契約なので、当初の見積もりを超えるリスクがある。
スケジュールを見積るときは、次の項目に注意が必要だ。
- 要求の洗い出しを行う
- リスクを分析する
- 設計、実装、統合を行う
- ユーザーとともに検証する
また、次のような問題に答えられる統計学も理解しておきたい。
予想されるプロジェクト期間が62週間で、分散(variance)が81週という大規模プロジェクトがあると仮定する。
「予定より18週間早くしてほしい」という要望が挙がってきたとする。
実現可能性は、何%か。
もし、わからないとプロジェクトの管理が苦手なプロ真似になってしまう。
「弊社は100%やりますよ。」という営業がいる会社とは契約しないほうがいいだろう。言葉に責任が感じられなく、信用に値しない。
では、どうやって求めるのか。
Zスコアを使って計算する。
Zスコアとは、標準偏差の数が母平均より上または下である度合いのことだ。
母平均と母集団の標準偏差がわかれば、Zスコアを計算できる。
母集団のすべての観測値を観測することが不可能な場合、無作為抽出を使用して標準偏差を推定できる。
Z = (Due date – expected completion date)/sqrt(project variance)
= ((62 – 18) – 62)/sqrt(81)
= (44 – 62)/9
= -18/9
= -2
エクセルなどで =NORMSDIST(-2)とすると標準正規分布の累積分布関数の値を求めることができる。
答えは、0.022750131948179となり、おおよそ2.3%となります。
つまり、97.7%は、無理なのだ。
知識はプレイン テキストに保存すること
プレイン テキストにはどのような利点があるのか。
- 透明性が保証される
- さまざまな活用ができる
- テストが容易になる
人間が読むことのできるデータは、可読できないデータに比べると、アプリケーションの枠を超て生き続けることができる。
データが長生きであれば、利用される機会も増えるのだ。
安全性の心配がある場合は、暗号化すれば良い。
ファイルの内容を変更して欲しくない時は、MD5 (128-bit)などを利用すればよいのだ。
常にソースコード管理を使用すること
ソースコード管理は、自動化と密接な関係がある。
リポジトリーから自動的に最新のソースコードを抜き出して、プロジェクトのビルドを行うように作りこんでおく。
真夜中に実行するようにして、その日のコーディングが他の部分に影響を与えていないかどうかを確認するための回帰テストも自動化するのが望ましい。
問題が発生した場合でも、過去のバージョンとの比較が容易にできるメリットもある。
筆者が過去に使用していたバージョン管理システムは、CVS、ClearCase、Gitだ。
機能も十分でかつ無料で使用できるGitが現時点ではオススメ。
パニックに陥らないこと
人は納期が目前に控えている時や、バグの原因をみつけようとやっきになっている時に、パニックになる方もいる。
これは経験値をあげることで克服できるのでどんどん経験しよう。そしてひとが嫌がることをするとあなたの優位性も上る。
また、第三者からくるバグ報告は、正確性が損なわれている場合もある。
そのため、十分な情報を得るためには、バグを報告してきた相手にも注意を払う必要があるだろう。
アルゴリズムのオーダーを見積る
ループや再帰呼び出しを含むコードを記述する際には、実行時間とメモリー要求の妥当性を判断しよう。
例えば、100件の処理を行うのに1秒かかるルーチンがあったする。
では、1,000件を処理するにはどれだけかかるでしょうか?
あなたのコードが、O(1)であった場合、1秒かかります。
Oといのは「オーダー(Order)」の頭文字であり、O()記法は測定対象(時間、メモリー等)の上限値を表すものだ。
次に、O(lg(n))の場合は約3秒またなければならないでしょう。
エクセルなどで、 =LOG(10,2)とすると値を求められます。
O(n)だと線形なので10秒なのに対し、O(n lg(n))だと33秒かかります。
エクセルなどで、=10*LOG(10,2)とすると値を求められます。
そしてコードがO(n^2)であった場合、100秒も待たなければなりません。
ちなみに、lg(n)は、log2(n)の省略形。
logって何?
logは、何乗すればいいのかを表す数。
例:
3^2 = 9 つまり、3を2回かけると9
log3(9) = 2 つまり、3を何回かけると9になるのか?
基本的なアルゴリズムのオーダーを見積もってみよう。
- 単純なループ: 1からnまで繰り返して実行を行う単純なループがある場合、そのアルゴリズムは、O(n)に近いもの、つまりnとほぼ同じ線形増加となる。
- ネストしたループ: ループの中にネストしたループがある場合、そのアルゴリズムは2つのループの上限値をm,nとしたO(m * n)になる。
これはバブルソートのような単純なソートアルゴリズムで、外側のループが配列の各要素を順に走査しながら内側のループでソート結果の要素を配置する場所を決定していくような場合に発生する一般的なものだ。 - 二分割: 各ループの中で対象データを二分割していくようなアルゴリズムの場合、それは対数O(lg(n))に近いものになる。
バイナリーサーチや二分木トラバースなどが有名だ。 - 分割統治法: 入力を分割して、その2つを独立したものとして操作したあとに、結果を結合するようなアルゴリズムは、O(n lg(n))となる。
例えば、データを2つに分割し、それぞれを再帰的にソートしていくクイックソートがある。 - 組み合わせ: データの順列を調べるアルゴリズムは、実行時間が長くなる。例えば、1から5の順列には、5!=5 * 4 * 3 * 2 * 1 = 120 種類の組み合わせがある。6要素の場合、計算時間は5要素の6倍の時間がかかる。
要求は拾い集めるものではなく、掘り起こすものである
要求とは達成する必要のある何かについて述べたものである。
例えば、こんな感じだ。
- 顧客データは、あらかじめ決められた人々によってのみ閲覧できる
- HDDの温度は、危険値をこえてはならない
しかし通常の場合、要求をきれいに切り出せるようなことは少ない。
最終的な目標は、要求通りのものを作るということではなく、ビジネス上の問題を解決するということなのだ。
あまり使われていない方法だが、ユーザーの要求を取り出す簡単な方法がある。
それは、ユーザーになることだ。
実際のシステムがどのように使われているか、という見識に加えて「あなたと一緒に、ここで1週間座っていいですか?」とお願いしてみる。
すると、ユーザからの信頼を得ることが出来き、コミュニケーション手段も確立できる。
手作業は危険である
人間はコンピュータのように繰り返し作業が得意ではない。
それを期待することも間違っている。
例えば、「特別定額給付金」のオンライン申請の確認を目視で行うという前提がそもそも間違っている。いったいどれだけの人件費がかかるのか。それとも、わざと雇用を創出しているのかもしれない。
話はそれたが、寝不足の担当者にデプロイメントをまかせる事も、ぜったいに避けるべきだ。それなら、いっそ自動化したほうがましだ。
疑わしいアドバイス
毎年少なくとも1つの言語を習得する
20代にはあてはまるかも知れませんが、 40〜50代で実践している人はいない。
実際周りでも見たこともないし、現場でもそのようなことは求められない。
逆にそんなスーパーなおじさん/おばさんプログラマがいたら教えてほしい。
現実的なおすすめは、プログラミング言語の検索数を集計した「TIOBE Index」をチェックし、トップ10のうち5つぐらいの習得するを目指すことだ。
最終決定などというものは存在しない
責任者が最終決定をしないと、プロジェクトは永遠に終わらない。
ゴーイングコンサーン(going concern)とも言われるが、企業が将来にわたって存続するという前提は幻だ。
2018年に倒産した日本国内企業の平均寿命は、23.9年だ。
果たして倒産後もそのプロジェクトは、続くのだろうか。
ある程度の妥協と落とし所は、念頭にいれたほうがいい。
そして、いきなり100点を目指すより、まずは90点を目指して、あとで改善すればいい。
偶発的なプログラミングを行わないこと
プログラミングは、科学の実験と違って、偶発的にコーディングすることはまずない。
また、猫がキーボードにのって間違って新しいプログラムが完成することも絶対にない。
しかし、思いがけないきっかけで、偶発的にバグを発見することはある。
まとめ
疑わしいアドバイスも記載されているが、ほとんどが今でも役に立つヒントだ。
これから達人プログラマーを目指す大学生や新社会人は、一度手にとってみてはどうか。
きっと役に立つだろう。
コメント