社内勉強会向けに、見積もりについて説明するパワポを作成したため、公開します!
見積もり概論
見積もりの必要性・手法・経験則について、簡単に説明しています。
詳細設計以降の作業の見積もりを行う場合は、見積もり手法と言うよりは、技術力の方が重要になります。
しかし、それ以前の工程の時点で見積もりを行う場合、具体的なものが見える前に見積もらなければならないという難しさがあり、見積もりがブレた場合の影響も大きいので、このパワポで解説するような知見が重要な意味を持ってきます。
上流工程を担うようになった場合に役に立つ知見なので、それまで頭の片隅に置いていただければと思います。
例外ケースは処理の始めに除外する
プログラムで何かしらの処理を記述する場合、本当に実装したい処理(本処理)に入る前に、例外ケースを除外するテクニックがあります。
このように記述することで、本処理では例外ケースを考えずに済むため処理内容を考えやすくなりますし、例外ケースの場合に時間がかかる本処理を実行しなくて済むようになるので性能面でもメリットがあります。
例として、競技プログラミングの問題を取り上げて説明してみます。
今回取り上げる問題は以下です。
100円玉がA枚、
10円玉がB枚あります。
X円を作る方法が何通りあるか出力しなさい。
ループ処理を実装して総当たりを行えばこの問題を解くことはできますが、その場合は性能面が犠牲になるため、望ましい解答ではありません。
今回は、ループ処理を使わずにこの問題を解いてみます。
(言語はJavaです。なお、本来は、標準入力を入力としますが、今回はソース中の定数を入力としています。)
【解答例】
・HundredYenTenYen.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
public class HundredYenTenYen { public static void main(String[] args){ /* 問題 * 100円玉がA枚、 * 10円玉がB枚あります。 * X円を作る方法が何通りあるか出力しなさい。 * 入力: A B X */ // 100円玉の枚数 int A = 6; // 入力 // 10円玉の枚数 int B = 25; // 入力 // 作りたい円 int X = 550; // 入力 System.out.println("入力:" + A + " " + B + " " + X); System.out.println("回答:" + execute(A, B, X)); } public static int execute(int A, int B, int X) { // ①作りたい円が100円玉・10円玉の合計金額を超えていないか確認 if ((A * 100) + (B * 10) < X) { return 0; } // ②作りたい円が10の倍数か確認 if (X % 10 != 0) { return 0; } // ③持っている10円玉の枚数で、作りたい円の10の位を実現できるか確認 if (B < (X % 100) / 10) { return 0; } // ④10円玉10枚の組はいくつあるか int BAfterPaidTensPlace = B - ((X % 100) / 10); int bulkOfTenTenYen = BAfterPaidTensPlace / 10; // ⑤100円玉だけの場合、作りたい円の100以降の位がどれくらい足りなくなるか int hundredsPlaceOfX = X / 100; int lackOfHundredYen = Math.max(hundredsPlaceOfX - A, 0); // ⑥10円玉で100円玉を代替するパターンがいくつあるか int patternOfReplacedHundredYenByTenYen = bulkOfTenTenYen - lackOfHundredYen; // ⑦総パターン数を返却 return 1 + patternOfReplacedHundredYenByTenYen; } } |
【実行例】
・100円玉だけで100以降の位を払え、10の位を払った時に10円玉10枚組が減らない場合
1 2 |
入力:6 25 550 回答:3 |
備考:以下の3パターンがある。
100円玉5枚+10円玉5枚
100円玉4枚+10円玉15枚
100円玉3枚+10円玉25枚
・100円玉だけで100以降の位を払え、10の位を払った時に10円玉10枚組が減る場合
1 2 |
入力:6 25 460 回答:2 |
備考:以下の2パターンがある。
100円玉4枚+10円玉6枚
100円玉3枚+10円玉16枚
・100円玉だけでは100以降の位を払えない場合
1 2 |
入力:6 25 840 回答:1 |
備考:以下の1パターンがある。
100円玉6枚+10円玉24枚
・持っている10円玉の枚数で、作りたい円の10の位を実現できない場合
1 2 |
入力:6 5 460 回答:0 |
・作りたい円が10の倍数ではない場合
1 2 |
入力:6 5 445 回答:0 |
・作りたい円が100円玉・10円玉の合計金額を超えている場合
1 2 |
入力:6 25 860 回答:0 |
この解答例では、「10円玉10枚の組み合わせは、100円玉1枚を代替できる」という点に着目し、④~⑦の箇所でパターン数を割り出しています。
そして、ポイントは、①~③で例外ケースを除外している所にあります。
①~③の例外処理を事前に噛ませることで、④~⑦に到達した時点で
・入力された金額は100円玉と10円玉で払い切れる
・入力された金額は必ず10の倍数である
・10の位を払う時に10円玉が足りなくなることはない
ということが保証されるため、④~⑦の処理を考えやすくなっています。
また、今回の例では当てはまりませんが、もし④~⑦が時間のかかる処理である場合は、例外ケースの場合に処理時間の短縮をすることもできます。
このように、例外ケースを事前に除外するテクニックが役に立つことがあるので、覚えておいて損はないでしょう。
いかがでしたでしょうか。
プログラムのアルゴリズムを考える上ではいくつかコツやテクニックのようなものがあるので、これからもそういった情報を発信できればと思います。
C#:外部コマンド呼び出しの方法
javaプログラムからの外部コマンド呼び出しは別の記事に掲載したのですが、C#でも同様に外部コマンド呼び出しが可能です。
今回の記事では、「画面から外部コマンドを呼び出し、外部コマンドで出力されたファイルを取り込む」という機能をWindows Fromで実現したサンプルプログラムを紹介します。
【サンプルプログラム】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { // プロセスを定義 Process p = new Process(); p.StartInfo.FileName = @"C:\tmp\HelloWorld.bat"; p.StartInfo.Arguments = ""; // プロセス実行 p.Start(); // プロセス終了待ち p.WaitForExit(); // 資源を開放 p.Close(); // 呼び出したバッチで生成されたファイルを読み込む using (StreamReader sr = new StreamReader( @"C:\tmp\a.txt", Encoding.GetEncoding("Shift_JIS"))) { label1.Text = sr.ReadLine(); } } } } |
【呼び出されるバッチ】
・C:\tmp\HelloWorld.bat
1 2 3 |
@echo off echo Hello World!> C:\tmp\a.txt exit 0 |
【実行結果】

↓

いかがでしたでしょうか。
プライベートでこのようなプログラムを作る機会があったので、記事として紹介してみました。
簡単な画面を作りたい時にC#のWindows Fromは便利で、今回紹介したような画面を実装すると社内ツールを作る時の表現の幅が広がったりします。
IT業界におけるメンタルヘルス対策
IT業界は、メンタルヘルス不調が出やすい業界であると言われます。
メンタルヘルス不調者が出てしまうと事業に悪影響がありますし、何より心情的に心が痛むものがあります。
この記事では、IT業界の特殊な背景と、IT業界でのメンタルヘルス対策について、簡単に書いていきたいと思います。
デリケートな話題ですので、読者のメンタルヘルスを悪化させる可能性がある内容は極力控え、客観的な記述を心がけます。
1.IT業界でのメンタルヘルス不調の多さ
2020年に「過去1年間におけるメンタルヘルス不調による連続1か月以上の休業をした労働者及び退職者割合」という政府統計が取られました。
この統計によると、1年間でメンタルヘルス不調により1か月以上休業する社員の割合が、インターネット附随サービス業は1.5%、通信業は1.1%、情報サービス業は0.9%であるとされています。100人いれば1人はメンタルヘルス不調により長期休暇を取っているという計算です。
(職場によってはこれより高いこともありますし、長期休暇を取らないまでもメンタルヘルスが不調のまま踏ん張っている社員がいることも予想されます)
これは全業界で1位・2位・3位であり、平均の0.4%と比べるとその高さがわかると思います。
2.IT業界にメンタルヘルス不調が多い理由
IT業界に限らず、一般的に「仕事の責任が重くプレッシャーを感じる」「仕事の裁量が少なく自分の仕事を自分でコントロールできない」といった環境では、メンタルヘルス不調が発生しやすくなります。
勿論、各種ハラスメントが横行している職場の場合は、それはメンタルヘルス不調を引き起こす主因になります。
そして、IT業界特有の理由としては、以下のようなものが考えられます。
■不規則な勤務が多い仕事である
IT業界では、長時間残業や深夜作業・休日作業を余儀なくされることがあります。
開発では納期前に「デスマーチ」と呼ばれる追い込みを強いられることがあります。
36協定が遵守されていたとしても、1ヶ月100時間弱の長時間残業を強いられる可能性があります。
また、保守・運用では、システムの都合に合わせた勤務が必要になることがあります。
システムがサービス時間外となる時間帯でないとできない作業があるためです。
そのため、深夜作業や休日作業が必要になることがあります。
更に、緊急のシステム障害の場合は、そのような勤務が予定外で発生します。
このような過大で不規則な勤務は、プライベートの充実や睡眠時間の確保を難しくさせます。
当然、メンタルヘルス不調を抱えるリスクは高まります。
■孤独感を感じやすい仕事である
IT業界はPCの前に座っていることが多い仕事であり、直接会話する機会は少ないです。
また、IT業界に多い客先常駐という形態は、孤独感を強める要素になり得ます。
客先常駐では自社の社員が居ない・少ないという環境で仕事をするため、良く知っている人とのつながりを感じながら仕事をするという形にはなりにくいです。
コロナ禍でIT業界に浸透したテレワークも、孤独感を強める要素になり得ます。テレワークでは非公式のコミュニケーションが発生しにくいため、人となりを知りにくくなったり、どう思われているのかわかりにくくなったりします。
人との繋がりを感じにくく孤独感があるというのは、メンタルヘルスにマイナスです。
■褒められることが少ない仕事である
特に保守・運用に言えることですが、この仕事は縁の下の力持ちな面があります。
また、システムは動いて当たり前と思われやすいです。
そのため、システム稼働を維持していたとしても、褒められることは少ないです。
逆に、システム障害を発生させてしまうと叱責されてしまいます。
このように、仕事の中で自己肯定感を感じることが少ないので、メンタルに厳しい仕事と言えます。
■変化が激しい業界である
IT業界で使われる技術は変化が早く、次々と新しい技術が生まれます。
また、若年者は知識の習得が早い上、教育機関で新技術を学んでくることもあります。
そのため、現場で最前線に立ち続けるには勉強の継続が欠かせません。
このことは余暇の時間を減らすことになりますし、プレッシャーにも悩まされます。
なお、これはIT業界に限りませんが、出世やステップアップにより、現場仕事から管理側の仕事へ移行することもあります。
この場合は、技術の変化に悩まされることは少なくなりますが、仕事内容が変わることで、人によってはやりがいを失うことがあります。
■メンタルヘルス不調を抱えやすい社員が多い
IT業界の技術者には、高い論理的思考力が求められます。
また、ある種の発達障害者は論理的思考力が比較的高いとされています。
そのため、発達障害者にお勧めの職業として技術者が挙げられることが多いです。
(実際、従事者も比較的多いと思います)
しかし、発達障害者は人とのコミュニケーションに難を抱えることが多いため、メンタルヘルス不調を併発することが少なくありません。
コミュニケーションが少ないIT業界といえども、チームワークは必要であり、職場に発達障害への理解が無い場合は、メンタルヘルス上リスクとなります。
発達障害者ではないとしても、仕事内容によっては、メンタルヘルス上のリスクが高い性格を持つ人物が求められます。
コンピューターを動かす上では論理性が求められ、曖昧さは許されないため、完璧主義な性格が求められる面が出てきます。
しかし、この完璧主義は、メンタルヘルス不調のリスクが高い性格でもあります。
3.メンタルヘルス不調の影響
メンタルヘルス不調になった社員は、パフォーマンスが悪くなります。
そして、最終的には休職や退職をせざるを得ない状態になります。
(休職・退職があまりにも多い場合、悪評が立ち採用活動が困難になることがあり、最悪の場合は健康被害のために訴訟に発展することもあります)
具体的には、メンタルヘルス不調になった社員には以下の症状が発生します。
■前兆となる症状
- 勤怠が乱れ始める(遅刻や突休をするようになる)
- 声のトーンが暗くなる、ネガティブな発言が増える等、明らかに元気がなくなる
- 頭痛が増える、風邪を引きやすくなる等、体調不良が増える
■IT業界で良く目にする病名
メンタルヘルス不調の病院での診断名は以下の通りです。

なお、メンタルヘルス不調の症状により通常の就労が困難になった場合、精神障害者保健福祉手帳の交付を受けるケースもあります。
日常生活を自力で送れるが就労が困難、という程度の場合は、精神障害2~3級となります。
■メンタルヘルス不調の治療と経過
メンタルヘルス不調を病院で治療する場合、治療で即効性が高いのは投薬です。
しかし、投薬治療には副作用もあり、眠気といった仕事のパフォーマンスを落とす副作業もあります。
また、病院から診断書をもらい休職を余儀なくされるような強い症状が現れた場合、休職期間を終えて復帰しても再び休職してしまう可能性が少なくありません。復帰を急ぐ場合は特にその傾向が強くなります。
仕事の中で強いストレスを感じる経験をしてしまっており、仕事をする中でその経験が想起されるので、周囲の理解とサポートがなければ復帰は難しいものになります。
4.メンタルヘルス不調の対策
一般的に、メンタルヘルス不調への対策は以下のようなものになります。
■セルフケアの推進
研修を通して、各々の社員に以下の知識を身につけさせることで、メンタルケアを各々の社員自身で行うことができるようにし、メンタルヘルス不調の減少に期待できます。
研修で伝える内容は、厚生労働省や医療機関等の信頼できる機関が発信する情報に準ずることが望ましいです。
- ストレスやメンタルヘルスに関する正しい知識
- ストレスマネジメントやメンタルケアの方法
■職場でのメンタルヘルス対策の実施
メンタルヘルス不調を招くような要素を取り除いたり緩和したりする対策を職場で行うことも重要です。
例えば、深夜の労働時間が長くなりすぎないように勤務時間をシフトするのは良い対策です。
ただし、良かれと思った対策に効果が無い/逆効果となることも良くあるので注意が必要です。少なくとも、他人の気持ちがわかることを前提とした対策は厳禁です。見た目や口先だけで他人の内面を知ることは極めて困難ですし、本当にメンタルヘルス不調の場合は自尊感情が損なわれているケースが多くデリケートな対応が必要だからです。
ねぎらいのためや本音を聞き出したりするためにメンタルヘルス不調対策のつもりで半ば強引に飲み会に誘う、というのは日本の職場では見られがちですが、飲み会でストレスを感じるやりとりがされたり睡眠時間が削られたりして逆効果になる可能性があります。
職場で適切な対策を行うためには、上長にメンタルヘルスに関する正しい知識が必要です。
■会社全体でのメンタルヘルス対策の実施
メンタルヘルスは敏感で難しい分野ですので、職場での自助努力だけではなく、外部の専門家や社内の専門担当者、例えば、産業医や衛生管理者、保健師、人事・労務担当者が支援することも重要です。
全社的な施策や、長時間労働者へのヒアリング、職場でのメンタルケアのサポート、外部機関との連携等は、このようなポジションの人物でないと実施が難しいです。
■社外機関を用いたメンタルヘルス対策の実施
厚生労働省や中央労働災害防止協会、商工会議所、健康保険組合といった社外の機関もメンタルヘルス対策を推進しています。
具体的には、産業保健情報の提供、健康相談窓口の開設、アドバイザーや講師の個別訪問、といった活動に取り組んでいます。
社内だけではリソースやノウハウが足りない場合は、こういった社外機関によるサポートを得ることも重要でしょう。
下記のような助成金制度を利用することもできます。

いかがでしたでしょうか。
私はメンタルヘルスについて専門的な知識は持ち合わせていないので、このような重いテーマを投稿することには少し葛藤がありました。
しかし、IT業界とは切っても切れないテーマであり、またIT業界に関わる方々が知っておくべきテーマであるとも思ったため、投稿に至りました。
何かの参考になれば幸いです。
処理時間はデータ量に比例するとは限らない
処理時間(計算量)はデータ量に比例するとは限りません。
例えば、データ量が10倍になったからと言って、処理時間も10倍になるとは限りません。
処理時間が何倍になるかは、アルゴリズムにより決まります。
アルゴリズム次第では、データ量が10倍になった時に処理時間が100倍になることも有り得ます。
今回は、試しに、Java作成したソート処理の実行時間を測ってみます。
アルゴリズムはバブルソートです。
【サンプルコード】
・BubbleSort.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
import java.util.ArrayList; import java.util.Collections; public class BubbleSort { public static void main(String[] args) { // データ量(どちらかの行をコメントアウト) int num = 10000; // int num = 100000; // ソート対象の配列 ArrayList<Integer> array = new ArrayList<>(); for (int i = 0; i < num; i++) { array.add(i); } Collections.shuffle(array); // 回答の配列 ArrayList<Integer> answer = new ArrayList<>(); for (int i = 0; i < num; i++) { answer.add(i); } // ソート処理実行 long startTime = System.currentTimeMillis(); sort(array); long endTime = System.currentTimeMillis(); // 回答通りか確認 int diffCount = 0; for (int i = 0; i < num; i++) { if (array.get(i).intValue() != answer.get(i).intValue()) { System.out.println((i + 1) + "つ目の要素の内容を出力"); System.out.println(" 結果:" + array.get(i)); System.out.println(" 回答:" + answer.get(i)); diffCount++; } } if (diffCount == 0) { System.out.println("差異無し。"); } // 秒数出力 System.out.println((endTime - startTime) + " ミリ秒"); } static void sort(ArrayList<Integer> array) { // 左から順番に値を確定させていく // 添字の最小は0、最大はarray.size() - 1 for (int i = 0; i < array.size() - 1; i++) { // 走査は右から for (int j = array.size() - 1; j > i; j--) { // 入れ替え処理(左が右より大きければ入れ替え) if (array.get(j - 1) > array.get(j)) { int tmp = array.get(j - 1); array.set(j - 1, array.get(j)); array.set(j, tmp); } } } } } |
【実行時間】
・データ量が10000レコードの場合
1 2 3 |
1回目:1272ミリ秒 2回目:2826ミリ秒 3回目:1075ミリ秒 |
・データ量が100000レコードの場合
1 2 3 |
1回目:335986ミリ秒 2回目:305728ミリ秒 3回目:289040ミリ秒 |
以上のように、データ量が10倍になった場合に、実行時間も100倍(実測ではそれ以上)になりました。
なぜ実行時間がデータ量に比例しないのかと言うと、このアルゴリズムでは二重ループが発生するからです。
二重ループの中の処理が行われる回数は、10000レコードの場合は「1万 * 1万」(正確には「1万 * 9999」)回ですが、100000レコードの場合は「10万 * 10万」(正確には「10万 * 99999」)回となり、100倍の差となります。
この差が、実行時間にも反映されます。
専門用語で言うと、このような概念は「O(オーダ)」と呼ばれます。
(詳しくは、以前の記事で紹介しています)
実務でも、大量のデータを処理する必要がある場合は、「O(オーダ)」の概念や、最適なアルゴリズムを意識する必要があります。
基礎的なアルゴリズムは、情報処理技術者試験で学ぶことができます。
また、競技プログラミングでは最適なアルゴリズムを考えさせる問題が頻出なので、詳しく学びたい方は手を出してみると面白いと思います。
いかがでしたでしょうか。
「処理時間はデータ量に比例するとは限らない」というのは、アルゴリズムや性能問題を学んだことがない人にとっては意外なことだと思います。
システムには性能問題(Webページの動作が遅い、夜間バッチが決められた時刻までに終わらずにサービス開始時刻になってもシステムを利用できない、等)がつきものです。
そうした性能問題は、データ量の増加に対して処理時間が指数関数的に増えることで引き起こされていることも少なくありません。
この記事を通して、アルゴリズムや性能問題への興味を持つ人が一人でも増えれば幸いです。