汎用機システムの開発が基本情報技術者試験の復習になった話

## はじめに
初めまして、みやもとと申します。

大学卒業後にSI企業に入社、以降は一時期他業種に寄り道しつつ出戻りしまして、現在おそらくサーバサイドエンジニアです。
キャリア最初の10年ちょっとをほぼ汎用機開発でCOBOLプログラマとして過ごし、その後Javaに技術転換してからはその時々でCOBOLとJavaを行ったり来たりしています。

汎用機開発の現場はほぼ一貫して
・z/OS（IBMメインフレーム）
・IBM DB2
という、IBMの巨象ぶりを思い知る環境でした。
富士通とか日立の現場もほんのちょっとだけ経験はしました。


この記事ではその経験を振り返ってふと思った、『基本情報技術者試験の内容と汎用機開発は知識的な相性が良いのかも？』というお話をしたいと思います。

::: note
この記事は特に以下のいずれかに当てはまる人に読んでいただけると嬉しいです。
+ 基本情報技術者試験の受験を考えている
+ 既に基本情報技術者試験に合格している
+ 勉強した内容を実際使うことがあるのか疑問に思っている

こんなこともあるんだ、ぐらいに思っていただければ幸いです。
:::


::: note warn
この記事内の『基本情報技術者試験の内容』は私自身の受験当時の記憶に基づくものです。
現在の同試験の内容には必ずしも当てはまらないと思いますのでご了承ください。
（COBOLも基本情報技術者試験の出題言語から外れて久しいですね……）
:::

## データ定義とパック10進数
パック10進数、という単語は基本情報技術者試験の受験勉強中に知りました。
>パック10進数とは、コンピュータで数値を表現する形式の一つで、2進化10進数（BCD：Binary-Coded Decimal）を拡張し、末尾に数値の符号を表すコードを追加したもの。1バイトで1桁を表す「ゾーン10進数」（アンパック10進数）に比べ少ないデータ量で数値を表すことができる。
>[IT用語辞典 e-words「パック10進数とは」](https://e-words.jp/w/%E3%83%91%E3%83%83%E3%82%AF10%E9%80%B2%E6%95%B0.html)

ついでに2進数とか16進数もその時期に初めて見ましたが、それはさておき。

たとえば、COBOLプログラムでこんな定義があったとします[^1]。
[^1]:ここから先いくつか図が出てきますが、あくまで画面イメージであり実際の画面とは異なります。

![COBOLのデータ定義イメージ図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3477580/f3e70731-aae0-76bf-8b6a-30396e0fb9a5.png)

かなりざっくりのイメージ図ですが、プログラムで読み込むインプットファイルの項目定義部分になります。
商品コードを文字、単価をパック10進数、在庫数をゾーン10進数で定義した明細ですね。
01の行で入力データ1件全体、03の行でそれぞれの項目を定義して、「PIC」以降に項目のデータタイプと項目長を記述します[^2]。
[^2]:COBOLでは最下位レベル以外で項目長やデータタイプの定義が不要です。図の場合、01レベルは5+4+3=12バイトの文字扱いになります。

括弧の中の数値がそれぞれ項目の桁数です。
データタイプはだいたい1文字で表されて、「X」は半角文字、「9」は数値、かつ「COMP-3」とついているのがパック10進数、ついていないのがゾーン10進数となります[^3]。
[^3]:実際には片方だけゾーン、パックにするということはあまり無くてタイプをそろえることが多いのですが、説明の都合上定義を分けています

この定義のファイルをエディタで開くとこんな感じ。

![ISPFエディタ画面イメージ図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3477580/0adde0fe-c9b0-d3ac-4841-5632828c691a.png)

項目3つのうち、パック10進数で定義した単価だけがぱっと見読めない状態になっています。
さらにヘキサ表示[^4]にしてみるとこう。
[^4]:16進数での表示。くわしくは[IBM](https://www.ibm.com/docs/ja/zos/2.2.0?topic=commands-hexdisplay-hexadecimal-characters)のページをご参照ください。

![ISPFエディタ画面ヘキサ表示イメージ図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3477580/c00d0488-a7db-4318-2e9e-5b46937cb796.png)

四角で囲った部分が単価部分です。左上から順に上から下、左から右に「0001000C」と読みます。
最終桁のCは正負符号を表すので、前ゼロを外して「+1000」ですね。

パック10進数は目視だと読みづらいですが、こうして見ると「パック10進数を使うと項目の長さがゾーン10進数の半分に収まる」というのが実感としてわかりやすいのではないでしょうか。
符号合わせて8桁、ゾーン10進数なら8バイト使う数値が4バイトに収まるわけです。

汎用機で構築されたシステムは大抵の場合かなり年季が入っていて、つまりはそれだけ業務のシステム化に早く取りかかった大手企業、とりわけ金融系に多い印象があります。金融系に多いということはそれだけ金額項目＝桁数の多い数値項目が多く、また大企業ゆえに扱うデータも何万、何十万件単位になります。

たとえば1年間取引先とのお金の出入りを1ヶ月単位で保持するデータを処理するとして、1項目13桁で定義するとゾーン10進数なら13バイト×12ヶ月分で156バイト。パック10進数なら7バイト×12ヶ月の84バイト。
1件のデータでもだいたい半分ぐらいのサイズになるのですから、大量データならなおのこと差は大きくなりますね。

## JCLと容量計算
1シリンダあたりのトラック数、1トラックあたりのブロック数、1ブロックあたりのバイト数を指定して、このレコード長で何件データを書き込む場合に必要なシリンダの数を……という容量計算の問題は今でもあるのでしょうか。
私の頃は多分ありました。あったはずです[^5]。
[^5]:検索してみたらヒットしたのが[平成17年秋期問題](https://www.fe-siken.com/kakomon/17_aki/)でした。20年近く前……

話は変わりますがJCLをご存じでしょうか？
汎用機のバッチ処理実行で使う「Job Control Language」（ジョブ制御言語）というもので、ステップごとに使用するプログラムや入出力ファイルを記述するのに使います。
Linuxでいうところのシェルスクリプトを想像していただければだいたい合ってます。
JCLではしょっちゅう容量計算をやります[^6]。
[^6]:環境や条件によっては、機械側で勝手に計算してくれるケースもあるようです。

たとえば出力ファイルの定義について、JCLではこんな感じで記述します。

![JCL定義イメージ図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3477580/239fb1c8-5a77-8c9a-5211-c023b45b3083.png)

全部を詳しくやっていくと[IBMの解説書](https://www.ibm.com/docs/ja/zos/2.3.0?topic=SSLTBW_2.3.0/com.ibm.zos.v2r3.ieab600/toc.html)をひととおり読むことになるのであくまでざっくり。
プログラムの出力ファイルに関する定義で、「DSN」がデータセット名（ファイル名）、「DISP」はファイルを新規に作るのか既存を使い回すのか、処理に失敗したら削除するのかしないのか、等を決めています。
「UNIT」は書き込み先の記憶装置の種類で、「DCB」の中身と「SPACE」の中身が容量計算が必要なところですね。

「LRECL」はレコード長、データ1件書き込むのに必要なバイト数です。これはCOBOLのプログラム側で定義した入出力ファイルのバイト数になります。

「BLKSIZE」はそのままブロックサイズです。だいたいの場合、決められた最大バイト数[^7]に収まるLRECLの最大公倍数を使います。1ブロック内に何件書き込むかの定義をするわけですね。
[^7]:1ブロック最大27998バイト、となんとなく覚えていたのですが、[こういうこと](https://arteceed.info/?p=1190)のようです。

「SPACE」は書き込み時に確保する新規スペースです。私が現場でよく使ったのは「TRK」または「CYL」でした。それぞれトラック、シリンダを表していて、ファイルの書き込み用にあらかじめ何トラック、または何シリンダ確保するかということを定義します。

1トラックあたりのブロック数や1シリンダあたりのトラック数は書き込み先の設定を参照したり現場の開発環境資料を確認すれば解るので、データの出力件数に合わせて確保スペースを計算します。

ちょっと例を挙げてみます。
出力ファイルのレコード長（LRECL）が80バイト、実行環境上は1ブロック最大27,998バイト、1トラックのブロック数が2、1シリンダ内のブロック数が15という場合なら、1ブロック内に出力できる最大数は349件（1レコード80バイト×349件＝27,920バイト＜ブロック最大27,998バイト＜1レコード80バイト×350件＝28,000バイト）なのでBLKSIZEには「27920」を設定します。
SPACE指定は出力ファイルが何件ぐらいになるかの見積もりによって変わりますがとりあえず500件ぐらいで考えましょう。1ブロックに349レコード書き込むのであれば、500件なら500÷349＝1.4……≒2ブロック必要になります。
1トラックには2ブロックあるので、500件書き込むのであればちょうど1トラック必要、という計算になります。

実際にはブロックサイズ最大ぎりぎりまで使う指定はしないこともありますし、出力レコード件数にも余裕を持たせることが多いのですが、わりと容量計算の問題そのままじゃないですか？

## おわりに
知識を実感するには使ってみるのが一番ですが、そういう意味で基本情報技術者試験の内容と汎用機の開発は結構相性が良かったのではないかと思います。
私の場合は「なんとなく知っている知識」が実際に業務で使える段階になったところで勉強自体が楽しくなるので、学習のモチベーション維持という意味でも使う場所があったのはラッキーでした。

この手の試験知識の実践の場として教育用の汎用機システムとか用意して触れるようなところがあればいいんですが。
それであわよくば若いCOBOL経験者増えてくれないかな、と思ったりするんですが……難しいですよね。
先述の通り既にCOBOLは出題範囲からも外れていますし、パック10進・ゾーン10進というのも聞かなくなっているとか。

でも、おそらく試験範囲が技術の進歩より先に行くことはないでしょうし、案件は最先端よりちょっと古いぐらいのところが最多になる印象があります。
就職時点の私にとって「ちょっと古いな」というCOBOLの経験が理解に役立ったわけですし、ここ数年で受験勉強されてる人も「ちょっと古いな」と思うような言語や開発環境でその知識を実感できるかもしれません。
~~まさかとは思いますが、Javaはまだその枠になってはいないですよね……？~~

最後に、COBOLやメインフレームに興味を持ってくださった方は以下サイトをご参考までに。

http://www16.plala.or.jp/hiyokogumi/top.html

https://arteceed.info/


## 追記
所属OrganizationであるTECH WOMAN KANSAIは関西女性エンジニア限定コミュニティです。
オンラインもくもく会やオフラインイベント等で関西の女性エンジニアの「居場所」を作ることをテーマとしていて、みなさん気さくにおしゃべりしたり勉強したりしているので、ご興味ある関西在住の女性エンジニアは是非！

https://qiita.com/organizations/tech-woman-kansai

https://tech-woman-kansai.connpass.com/