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などで報告されている事例をベースに、各レベルのプログラマが犯しがちな誤り・望ましくない行動パターンの例を示しています。

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

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

2019/06/29 追記:「偶数/奇数の判定」の話が流れてきたので追記。またレベル7.5程度と思しき事例を観測したので追記。 2023/07/30 追記:その後も事例を見つけるたびに編集している。レベル0の事例を追記。

*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://twitter.com/EzoeRyou/status/1661918173023846400

*8:https://x.com/tokoroten/status/1782450760938344882

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

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

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

*12:https://xtech.nikkei.com/atcl/nxt/column/18/02629/110200002/

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

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

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

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

*17:https://twitter.com/dayux_crypto/status/1711052638144573752

*18: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

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

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

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

*22:https://twitter.com/daemon_novel/status/1652635412836532225?s=46&t=97fp9HGw603Pb6zFqhm91Q

*23:https://twitter.com/snmimizk/status/1652645701049024512?s=46&t=97fp9HGw603Pb6zFqhm91Q

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

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

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

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

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

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

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

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

*32: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

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

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

*35:https://x.com/kmt_t/status/1733265378204434544?s=46&t=97fp9HGw603Pb6zFqhm91Q

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

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

非手続き型言語における機械的計測可能で客観的なテスト充分性の指標

プログラムをテストするときに、テストの充分性を示す指標として、C0とかC1とかのカバレッジ(コードカバレッジ)がよく使われます。

C0やC1は、実行されたことがない順次処理や、分岐したことがない分岐処理が、プログラム中に残っていないか計測するための指標です。なので、C0やC1は、順次処理と分岐の組み合わせでできている *1 手続き型言語に対しては、意味のある指標だと言えます *2

C0やC1の利点として、客観性が高いことが挙げられます。ソフトウェアの機能に対するテスト観点の網羅性(テストカバレッジ)などは、ソフトウェアに対する理解の度合いや、ソフトウェアの機能の数えかたといった、計測者の主観によって指標値が変わってしまいますが、C0やC1はそういった影響を受けません。また別の利点として、機械的に計測が可能である点が挙げられます。テストカバレッジを計測する場合、テストケースとソフトウェアの機能一覧とを人間が対応づける必要がありますが、C0やC1はソースコードと直接対応付けられ機械的に計測が可能です。

一方、C0やC1の別の欠点として、順次処理や分岐を直接記述しない非手続き型言語ーたとえばSQL正規表現ーでは、C0やC1を計測できなかったり、たとえ計測できたとしても指標として意味を成さなかったりします。かといって、テストカバレッジには客観性の点に問題があります。

そこで本研究では、非手続き型言語に対してテストの充分性を示す、機械的計測可能で客観性の高い指標を提案します……という論文があれば是非読みたいんだけど、誰か知りませんか。

*1:繰返しは分岐の特殊なケースとして扱います。

*2:もちろんC0やC1では計測できない充分性もあります。ここでは、テストの充分性を表す一つの観点として辻褄の合う説明ができる、ということを指して、C0やC1が「意味のある指標」であると言っています。

文化的まちがいさがし - 子供は独立した個人か

  • (A) 子供をあるがままに、独立した個として認める。あるがままに認めるがために、乳幼児の知能を犬やイルカと同程度と考えることを厭わない。
  • (B) 子供を大人に従属する存在と考える。大人に従属する存在であるがゆえに、乳幼児の知能を犬やイルカと同程度と考えることを忌避し、小さい大人として扱う。

当然、組み合わせとしては「(C) 子供を独立した個として認め、小さい大人として扱う」という文化があってもおかしくないのだが、自分の周りには(A)か(B)のどちらかしかいなかった。

文化的まちがいさがし - 学校で日本語をいちから教えるか

  • (A) 日本語のリスニング・リーディング・スピーキング・ライティングはすべて小学校でいちから教えてくれないと困る。母語が日本語でない人に限らず、母語が方言だったり、日常の知識は口伝という土地の人もいるから。
  • (B) 日本語のリスニング・リーディング・スピーキング・ライティングを小学校でいちから教えていたら、肝心の教育が行えない。ドイツでは、自国語を母語としない難民が多い地域で、授業が成り立たなくなって困っていたはず。

小学校に入学する前に、幼稚園に通っていた人が多いか、保育園に通っていた人が多いかによっても、(A)か(B)かが違うかもしれませんね。

文化的まちがいさがし - 三分間スピーチ

  • (A) 学校に三分間スピーチがある文化。初めて三分間スピーチをやったのは小学校高学年くらい。
  • (B) 学校に三分間スピーチがない文化。社会人になって、初めて三分間スピーチというものを知った。

私は(A)だったこともあって、The peanutsのshow and tellのエピソードを見て「三分間スピーチかな」と分かったんどけど、(B)の人から見たら意味不明だよね、show and tell。