Lazy Diary @ Hatena Blog

PowerShell / Java / miscellaneous things about software development, Tips & Gochas. CC BY-SA 4.0/Apache License 2.0

平均的プログラマ以前向けのスキルの指標

Java経験年数〇年以上のプログラマ募集」みたいなフレーズ、よく聞きますよね*1。求めるスキルを示すのに「〇〇言語でプログラミングができること」あるいは「〇〇言語経験年数〇年以上」という表現を使うことはよくあるようです。ですが、このレベルの記述では粒度が荒すぎて、求めるレベルとのスキルアンマッチが容易に発生しそうです。

この問題は、客観的に評価できるスキル標準を利用することで解決できそうです。コンピュータソフトウェアエンジニアのスキルレベルを示す指標としては、ISO/IEC 24773*2・英国SFIA*3・IFIP IP3*4、国内ではIPAITスキル標準モデル*5情報処理学会のCITP制度*6などがあります。しかしこれらの指標は、スキルレベルを示すと同時に、目指すべきスキルのモデルケースを示すものでもあります。したがって、これらの指標はエンジニアの平均的なレベルよりも高い水準に設定されています。

一方で、IPA ITスキル標準モデルカリキュラム(レベル2) は、経験の浅いプログラマ向けにレベルが低めの指標になっていますが、いかんせん教育用の指標のため、募集に使うには粒度が細かすぎ、また具体例が少ないという問題があります。 ほかの例としては SFIA 6 プログラミング/ソフトウェア開発 がありますが、逆にこれは粒度が荒すぎます。

そこで本記事では、まったくの素人から平均的なプログラマまでを対象としたスキルレベルの指標を作成してみました。Webなどで報告されている事例をベースに、各レベルのプログラマが犯しがちな誤り・望ましくない行動パターンの例を示しています。

  • レベル1:プログラムを書こうとするが、「コードは決まった文法で書かないと受理すらされない」ということを理解できず、プログラム言語の文法に沿わないコードを書き続ける*7
  • レベル2:文法に沿ってコードを書こうとはするが、自分の知っている他の文法と食い違いがあるために、そのプログラムの文法を受け入れられない。「イコール記号は代入を意味する」ということが理解できないケースなど*8*9
  • レベル3:ターゲットとしている言語の文法を受け入れることができ、その文法に沿ってコードを書こうとはするが、ループが理解できない。if文は理解できるため、リストの代わりに「userName1」「userName2」……のように大量の変数を並べて処理を書いたりする*10*11*12*13
  • レベル4:ターゲットとしている言語の文法に従ってコードを書くことができ、ループの概念も理解しているが、コンパイルを通せない*14。エラーメッセージにはコンパイラがエラーを検知した箇所が含まれているということを理解できない *15コンパイルエラーが発生したら、「プログラムを読み返して、怪しいと思った(多くの場合は見当違いな)場所を修正しては再コンパイル」をエラーが出なくなるまで繰り返す。
  • レベル5:ターゲットとしている言語のコードを書くことができ、コンパイルを通すことができる。コンパイルエラーは解決できるが、実行時エラーを解決できない。コンパイルが通ったからプログラムは完成だと報告を上げてくる*16*17
  • レベル6:実行時エラーが発生しても、めげずに立ち向かえる。エラーの原因を体系的に調査することはできないため、「プログラムを読み返して、怪しいと思った場所を修正しては再実行」をエラーが出なくなるまで繰り返す。結果として、プログラムの挙動が当初の想定から意図せず変わっていたりする*18
  • レベル7:実行時エラーログの存在は知っており、業務プログラムが出力した日本語のエラーメッセージは読める。一方で、スタックトレースや、英語のエラーメッセージは読めない*19。そのため、フレームワークやライブラリの内部でエラーが発生すると立ち往生してしまう。
  • レベル7.5:実行時エラーが発生した際に、スタックトレースをもとにエラーの原因箇所を調査できる。ただし、エラーメッセージ通りの修正しか行えない。たとえば、NullPointerExceptionが発生していたら、発生箇所の直前にnullチェックを入れるくらいしかできず、根本的な原因までさかのぼった修正(メソッドの戻り値がnullにならないよう引数を確認する、など)は行えない*20
  • レベル8:実行時エラーが発生した際に、スタックトレースをもとにエラーの原因箇所を調査できる。スタックトレースや英語のエラーメッセージを読んで意味が理解できる。一方で、スタックトレースが出力されなかったり、スタックトレースが直接原因箇所を示さなかったりするエラーは解決できない*21
  • レベル9:実行時エラーが発生した際に、体系的に原因を調査できる。スタックトレースがなくても、printfデバッグやデバッガの機能を頼りにエラーの発生箇所を特定できる。エラーの原因を調査し、正しいかどうかは別としても簡単な修正が行える。
  • レベル10:ターゲットとしている言語のプログラムを読み書きでき、デバッグも行える。ただし、コードを書く際には擬似コードなどで詳細に書かれた内容をもとにする必要があり、与えられた仕様を元に一からコードを書くことはできない*22*23*24
  • レベル11:ターゲットとしている言語のプログラムを読み書きできる。与えられた仕様を元に一から自分でコードを書こうとするが、基本的にはググって見つかったサンプルコードをコピペして、変数名などを調整することで仕様を満たそうとする*25*26。作成したコードの中に、与えられた仕様と関係ない処理が混ざっていても、何のためにその処理があるのか理解しておらず、削除するのも怖いので、そのまま放っておく。
  • レベル12:ターゲットとしている言語のプログラムを読み書きできる。処理の流れが単純なプログラムなら、処理内容を把握できるし、自分で一から処理内容を考えることもできる。一方で、メソッド呼び出しのネストが深いプログラムでは、処理内容の把握は難しい。ソースコード上の記述の順序とプログラム実行時の動きの順序を区別していない*27
  • レベル13:ターゲットとしている言語のプログラムを読み書きできる。処理の起点がひとつだけであればプログラムの処理内容を把握できるが、コールバック処理・イベント処理・非同期呼び出しなどがある場合は把握は難しい*28
  • レベル14:ターゲットとしている言語のプログラムを読み書きできる。与えられた仕様を元に、コールバック処理・イベント処理・非同期呼び出しなどを使ってコードを書くことができる(利用法が適切とは限らない)。フレームワークホットスポットビジネスロジックを実装することはできるが、フレームワークなしでプログラムを書き始めることはできない。
  • レベル15:ターゲットとしている言語のプログラムを読み書きできる。与えられた仕様を満たすコードを自分で考えて書くことができるが、行数・性能の両面とも効率的なコードを書くことは難しい。テーブルルックアップで済む処理をif文の繰り返しやswitch文で実装したり、ハッシュテーブルを使うべき処理でリストを使ったりする*29*30
  • レベル16:ターゲットとしている言語のプログラムを読み書きできる。与えられた仕様を元に、コールバック処理・イベント処理・非同期呼び出しや、扱うデータに合った適切なデータ構造を、必要に応じて利用してコードを書くことができる。雛形コードがない場合でも、どのような単位でモジュールを構成すべきかをアプリケーションアーキテクチャをもとに検討して、与えられた仕様を満たすプログラムをスクラッチから開発できる。

レベル感が前後するところや、粒度がチグハグなところもありますが、プログラミングだけに焦点を当てた場合はこんなものではないでしょうか。上記の最高レベルでも、「SFIA 6 プログラミング/ソフトウェア開発」でいえばまだレベル3(5段階の真ん中あたり)程度と思われます。 また、もちろんこれ以外にも、マルチスレッド動作やレースコンディションを理解しているかとかの追加の指標が考えられます。そういった指標があれば、併用することもできるでしょう。

2019/06/29 追記:「偶数/奇数の判定」の話が流れてきたので追記。またレベル7.5程度と思しき事例を観測したので追記。

*1:例: https://jp.indeed.com/%E6%B1%82%E4%BA%BA?q=Java+%22%E9%96%8B%E7%99%BA%E7%B5%8C%E9%A8%93%22+3%E5%B9%B4

*2:https://www.ipsj.or.jp/dp/contents/publication/37/S1001-T01.html

*3:https://sfia-online.org/ja

*4:https://www.ipthree.org/

*5:https://www.ipa.go.jp/jinzai/itss/download.html

*6:https://www.ipsj.or.jp/citp.html

*7:https://cpplover.blogspot.com/2018/05/blog-post_29.html

*8:https://xtech.nikkei.com/atcl/nxt/column/18/00682/080700011/?P=1

*9:https://twitter.com/hamukazu/status/960538822764240896

*10:https://okwave.jp/qa/q2122395.html

*11:https://twitter.com/hamukazu/status/960538822764240896

*12:http://www.pro.or.jp/~fuji/mybooks/cdiag/cdiag.3.8.html

*13:https://twitter.com/daemon1995/status/842568074519707648

*14:https://www.google.com/search?q=%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84+site%3Achiebukuro.yahoo.co.jp

*15:直すべき箇所と違うところが出てくる場合があるからコンパイラのエラーメッセージは信用できないし、直す箇所は教えてくれるのに直し方は教えてくれないからコンパイラは意地悪だ、と捉えていたりする。

*16:https://okwave.jp/qa/q387393.html

*17:https://qiita.com/tennis99jp/items/a8c6e642a96af2cfc82c#comment-f5300ed09a87bc61c014

*18:https://twitter.com/s_makinaga/status/1184982724190318593

*19:https://twitter.com/lightwill0309/status/1185060448019697665

*20:https://www.sejuku.net/blog/65065

*21:https://teratail.com/questions/84870

*22:https://www.atmarkit.co.jp/ait/articles/1909/24/news007.html

*23:https://twitter.com/nyaocat/status/1191003348175966208

*24:https://xtech.nikkei.com/it/article/COLUMN/20130610/483742/

*25:https://twitter.com/nfujita55a/status/1059270130348122112

*26:https://qiita.com/tennis99jp/items/a8c6e642a96af2cfc82c#%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92google-%E6%A4%9C%E7%B4%A2%E3%81%97%E3%81%9F%E3%82%89%E3%83%93%E3%83%B3%E3%82%B4%E3%81%AE%E8%A8%98%E4%BA%8B%E3%82%92%EF%BC%93%E3%81%A4%E4%BB%A5%E4%B8%8A%E8%A6%8B%E3%81%A4%E3%81%91%E3%81%9F

*27:https://xtech.nikkei.com/it/members/ITPro/ITBASIC/20001004/2/

*28:https://xtech.nikkei.com/it/members/ITPro/ITBASIC/20001004/2/

*29:https://twitter.com/kazuho/status/1094927534842535936

*30:これについては自分の学生のころの経験もあります……