give IT a try

プログラミング、リモートワーク、田舎暮らし、音楽、etc.

「ポータブルなスキル」や「エンジニアとしての基礎体力」の重要性

先日、チーム内ミーティングでメンバー全員が今期の自己啓発目標を発表していました。
その中で多く目立ったのが「C#を習得する」とか「Perlを習得する」というような新しい開発言語を習得する目標でした。
最初は「新しい言語にチャレンジするのはいいことだよね〜」と思っていたのですが、後になってみると「ん?本当にそれで大丈夫かな?」という気持ちにもなりました。


新しい言語を習得したといっても、今まで使っていた言語と同じことを別の言語でやってみたって大して意味がありません。
例えば、COBOLをやってた人がVBで開発して、その後C#を使うようになったとしても、作ったプログラムがすべてCOBOLチックなものなのであれば、「C#ができます」というのは「C#の基本的な文法は理解しています」ということであって、「C#の特性を活かしたスマートなプログラム」や「C#らしいコーディング」ができるという証明にはなりません。


また、一言で「C#」といってもC#の文法さえ分かっていれば業務ができるわけではなく、実際にはASP.NETADO.NET、Windows Formなどのフレームワークに関する知識も不可欠になってきます。
特に最近では、LINQだの、Entity Frame Workだの、ASP.NET MVCだの、WPFだの、新しい.NET標準フレームワークが山ほど出てきているので、C#の文法だけでなく業務で必要となりそうなフレームワークも勉強する必要があるでしょう。


でも、一番大事なのは言語を問わずに使える「ポータブルなスキル」なんじゃないかと思います。
例えば、オブジェクト指向を理解していればJavaでもC#でもRubyでも、ある程度簡単に理解できます。
ポータブルなスキルはエンジニアに必要な基礎体力、基礎知識であるとも言えます。
例えば「ホワイトボックステスト技法ブラックボックステスト技法を理解しています」というのは「XXXの言語ができます!」というのに比べると地味ですが、ちゃんとしたテストを設計できないエンジニアが作るプログラムはどんな言語を使ったところで結局バグだらけ、ということにもなりかねません。


そんなわけで、色々な言語をつまみ食いすることよりも、もっと重要な「ポータブルなスキル」、「エンジニアとしての基礎体力」を挙げてみます。
※注意: 以下のリストは基本的に情報システム開発者を対象とします。

  • きれいなコード、保守性や拡張性の高いコード、堅牢なコードが書ける
  • リファクタリングを理解し、実践できる
  • 構造化プログラミングができる
  • オブジェクト指向プログラミングができる
  • 達人プログラマーに載っているようなプラクティスを理解し、実践できる
  • 代表的なテスト技法を理解し、実践できる
  • テスト駆動開発を理解し、実践できる
  • SQLを理解し、つかいこなせる
  • 正規表現を理解し、つかいこなせる
  • 文字コードを理解し、文字化けが発生しても慌てずに対応できる
  • HTTPを理解し、ブラウザやWebアプリケーションフレームワークの背後に存在する処理が想像できる
  • 基本的な見積り技法を理解し、単なる勘だけに頼らない見積もりができる


また、業務経験が3年以上あるような中級以上のプログラマであれば、以下のような技術や技法を理解し、「やろうと思えば一人でもシステム全体を構築できるようなスキル」をそろそろ身につけておきたいところです。


いかがでしょう?
新しい言語やフレームワークを学ぶのは楽しいですし、「新しいスキルを身につけた!」という実感もわきやすいです。
反対に上で挙げたようなスキルは地味ですし、本を読んでいても若干退屈になることがあります。
しかし、使用する言語や開発する業務対象ががらりと変わっても使い回しがきくのは絶対に「ポータブルなスキル」の方です。


おいらはこういう勉強はスポーツで筋トレをしたり、毎日走り込んでスタミナを付けたりすることに似てるんじゃないかなあと思います。
華麗なドリブルや格好いいシュートを決めること(=色々な言語やフレームワークをバリバリ使いこなすこと)をしようと思うなら、毎日シュートを撃つ練習ばかりしててもダメですよね?


先日のミーティングで「C#オブジェクト指向プログラミングをマスターする」みたいに「ポータブルなスキル」とセットで勉強しようとしている人はいいと思いますが、「とりあえずC#ができたらいい」とぼんやり考えている人がいたとしたら、少し目標設定を見直した方がよいかもと思いました。


P.S.
上記のようなスキルを身につけるための本を一冊ずつ紹介しようかな〜とも思いましたが、本については折に触れてこのブログでも紹介しているので「カテゴリー = 本」で探してもらうと色々出てくると思います。

C#プログラマのための理解度チェックリスト

前回のエントリでは「新しい言語を勉強したって、前に使ってた言語と同じような書き方をしてたら意味がない」という話をしました。
そこでC#を題材にして、C#を本質からマスターできているかどうかを確認するためのチェックリストを作ってみました。
これらの質問に対してすべて自分の言葉で説明できるのであれば、あなたはきっとC#をC#らしく使えているはずです。

  • interfaceって何のためにある?どういうときに使う?それがあったら何が嬉しい?
  • 抽象クラスや抽象メソッドって何のためにある?どういうときに使う?それがあったら何が嬉しい?
  • virtualって何?なんでJavaにはvirtualがない?
  • 名前空間って何?それがあったら何が嬉しい?
  • クラスって何?自分で新しくクラスを作る場合の注意点は何?(オブジェクト指向設計的な観点から)
  • クラスと構造体の違いって何?参照型と値型の違いって何?
  • フィールドやメソッドの可視性って何?可視性にはどんな種類がある?全部public宣言しちゃうとどんな問題が起きる?
  • staticを付けているメソッドや変数は付けないときと何が違ってくる?
  • newっていったい何してるんでしょう?
  • コンストラクタって何?普通のメソッドとどう違う?
  • thisっていったい何なんでしょう?
  • 配列、リスト、ディクショナリの違いってそれぞれ何?どういう用途で使い分ける?
  • ジェネリッククラスって何?ジェネリッククラスがあると何が嬉しい?IListとIList(T)の違いは何?
  • 下のコードはどうして左辺と右辺のクラスが違うの?
IList<string> hoge = new List<string>();
  • 以下のようなコードの問題点はどこでしょう?(ヒント:例外の使い方)
public bool DoSomething()
{
  try
  {
    DoIt();
  }
  catch (Exception e)
  {
    Log(e.Message);
    return false;
  }
  return true;
}
  • 「disposeパターン」「using文」「ガーベッジコレクタ」という言葉を織り交ぜて、C#におけるリソース管理について説明してください
  • ローカル変数、インスタンス変数、クラス変数の違いはそれぞれ何でしょう?
  • プロパティとメソッドの違いは何でしょう?
  • Javaでよく使われるgetter/setterメソッドとC#のプロパティの違いは何でしょう?
  • 下のコードは一見するとどちらもキャストを行っているように見えるが、後者は実際には型変換を行っていないのはなぜ?
int i = 30;
short s = (short)i;

object obj = GetSomeObject();
MyClass myClass = (MyClass)obj;
  • 下のコードは実行時にどのような違いが現れる?(ヒント:GetSomeTextMaybeNullというメソッド名からリスクを推測する)
object obj = GetSomeTextMaybeNull();
string s1 = obj.ToString();
string s2 = (string)obj;
  • 文字列の連結は「+演算子」ではなく、StringBuilderを使えって言われる理由は何?
  • 下のコードを実行したときに現れる違いは何?また、違いが現れるのはなぜ?「参照」という言葉を織り交ぜて説明してください。
string str = "Hello,";
AppendToString(str);
Console.WriteLine(str); // 文字列を表示

StringBuilder sb = new StringBuilder("Hello,");
AppendToStringBuilder(sb);
Console.WriteLine(sb.ToString()); // 文字列を表示

private void AppendToString(string str)
{
  str += "World!";
}

private void AppendToStringBuilder(StringBuilder sb)
{
  sb.Append("World!");
}
  • 不変クラス(immutableなクラス)って何?
  • ステートレスなクラス、ステートフルなクラスってそれぞれ何?
  • 深いコピー(Deep Copy)、浅いコピー(Shallow Copy)って何?
  • 以下のようなメンバを宣言するときはアッパーキャメルケース(AbcXyz)、ローワーキャメルケース(abcXyz)のどちら?
    • クラス
    • メソッド
    • プロパティ
    • インスタンス変数
    • メソッド引数
    • ローカル変数


チェックリストは以上です。
回答例はここには挙げませんが、以下のような本を読むとおそらく大半の問題に回答できるはずです。


Effective C#

Effective C#

More Effective C#

More Effective C#

.NETのクラスライブラリ設計 (Microsoft.net Development Series)

.NETのクラスライブラリ設計 (Microsoft.net Development Series)


そして回答できるようになればきっと、あなたが以下のリンクにあるようなコラムを書くことはないと思います。。。


http://el.jibun.atmarkit.co.jp/minagawa/2010/04/post-ebc4.html