基本情報技術者試験の科目Bで満点取ったので，対策方法をまとめた

初めまして！
2023年度にIT企業へ入社したraedionです。
会社から入社一年以内に基本情報技術者試験に合格するよう言われたので、勉強して受けたところ科目Bで満点をとれました！

![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436205/95c1e30d-95e3-892c-258e-9a478951f0fb.png)


そこで、私が満点を取るまでにやったことを記事に書こうと思います。

(2023年5月17日更新:無事に合格しました)

# 本記事の結論
この記事の結論としては以下の通りです。
- 科目Aは**午前問題の過去問を周回すれば問題ない**
- 科目Bについては、**IPAが公式に出しているサンプル問題を必ずやる**
    - そこで解けなかった問題を解けるようにする
- セキュリティ：**セキュリティの知識を問うていない**
    - 文脈から回答を容易に判断できる
- アルゴリズム
    - **プログラムの動きをなぞって挙動を追跡できるようにする**
        - ループ処理は周回ごとに書きながら動きを追う
        - 配列へ格納する処理があれば、実際に入れてみる
    - 配列の要素番号がどこから始まるか、問題文を見てしっかり確認する
        - サンプル問題だと**1が始点**

# 前提：2023年4月から大幅な変更
基本情報技術者試験は、2023年4月に試験内容が大幅に変わりました。
まず、従来の「午前試験」と「午後試験」が、「科目A」と「科目B」の区分に変更されて、出題傾向が以下のようになっております。

改定前までは以下のような内容でした。
| 試験 |内容 |問題数 |時間 |
|---|---|---|---|
|午前試験 |ITに関する幅広な知識を問う問題|80問|150分|
|午後試験 |特定分野に関する一定以上の知識を問う問題|11問から5問を選択|150分|

改定後は以下のようになりました。
| 試験 |内容 |問題数 |時間  |
|---|---|---|---|
|科目A |ITに関する幅広な知識を問う問題|**60問**|**90分**|
|科目B |**アルゴリズム**と**セキュリティ**に関して一定以上の知識を問う問題|**20問必答**|**100分**|

変更点は以下の通りです。
- 午前試験は問題数が少ない科目Aになった（=コンパクトになった)
- 午後問題は選択形式でなくなり、アルゴリズムとセキュリティの知識を問う形式になった

資格勉強をしたことがある人なら共感してもらえるかもしれませんが、多くの場合は過去問ベースで勉強すれば受かります。実際に、基本情報技術者試験も2023年3月までは過去問ゲーでした。

しかし、変更後は、午後の傾向がかなり変わり過去問で対策することができない状態になり、多くの人が不安に感じているのではないかと思います。
そこで、本記事では私自身がどんな対策をしたのか、簡単にまとめようと思います。

# 科目Aの対策
科目Aについては、以前の基本情報技術者試験の午前問題で出てきた問題をしっかり対策すれば十分対応可能です。
強いて言うならば、問題数が減少したことからテクノロジ分野が占める割合が増えたため、しっかり対策することが大事かと思われます。
私は以下を勉強に活用しました。
- 「ニュースペックテキスト　基本情報技術者試験」
     ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436205/455ad19f-ca89-98ba-3839-24a16591b6ce.png)
- [基本情報技術者過去問道場](https://www.fe-siken.com/fekakomon.php)

私の場合、以下の方法で学習していきました。
1. マネジメント分野とストラテジ分野をテキストで学習
2. 過去問道場で問題を解く
3. 間違えた問題があれば、間違えた分野を中心にテキストで復習
4. 2と3を繰り返し

これらを行うことで、本番には合格基準点である6割以上を取れました。

# 科目B
科目Bは、「アルゴリズム」と「セキュリティ」の二分野の計20問が出題されます。
問題数が20問しかなく、6割以上で合格なので、単純換算だと8問しかミスができません。
そのため一問を確実に正解していくことが求められます。

# 対策：サンプル問題を解く
以下はIPAが出しているサンプル問題のリンクです。
https://www.ipa.go.jp/news/2022/shiken/tsunen.html

https://www.ipa.go.jp/news/2022/shiken/tsunen.html

試験を受けるにあたり、サンプル問題を解く対策しかしていませんでしたが、実際に試験を受けた感想としてはサンプル問題だけでも十分対策になりました。

# セキュリティ問題
セキュリティについては、文章から答えが類推できるような問題が出題されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436205/22b2f8b5-ea16-6b1d-70d5-dd01dff101f1.png)
（出典：基本情報技術者試験（科目B試験）　サンプル問題セット）

この問題だと、共用PCを使った手続きから個人所有のPCでVPNを経由して事務的手続きができるようになったことに起因するセキュリティリスクを答えることが求められます。
しかし、選択肢を見るとツッコミどころ満載です。
- （二）は完全におかしい。個人のPCを使うようになったのになぜA社のPCを紛失するリスクが生じるのか？？？
- （三）については因果関係が成り立たない。個人所有PCからのVPN接続を許可したらフィッシングメールのURLをクリックするリスクが生じるわけではない
- （四）もおかしい。総務部員は今回実施した事業改変の文脈にない存在だから関係がない
 
以上のことから、（一）と（五）が答えだと定まります。
この問題に回答する際に必要となったのは、せいぜいVPNが何か知っていることくらいです。**科目Aをしっかり対策していれば特別何かする必要はない**と思われます。

# アルゴリズム問題
これについては、サンプル問題と実際の試験を受けてみた所感として **プログラムの動きをなぞって挙動を追跡**することが重要だと感じました。

例えば、サンプル問題の問8について考えましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436205/411dbe0b-ef47-ccbb-096b-8f6ddc9087b8.png)
（出典：基本情報技術者試験（科目B試験）　サンプル問題セット）


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436205/3c6215d5-ade2-7a1c-6d77-cb0695eb2678.png)
（出典：基本情報技術者試験（科目B試験）　サンプル問題セット）


この問題では、キューに優先度が付与されたデータを順次格納して、それを順番に引き出す処理をしています。
キューはFIFO(First In First Out)のデータ格納方式であり、今回はそこに優先度の概念が追加されています。
つまり、優先度が高い要素が存在すればそれらの中からFIFOに準拠したデータ取り出しを行うようなプログラムが組まれています。

また、プログラム中のメソッドについても仕様が定義されているため、あとは一行ごとに動きを追いデータの遷移を確認していけば最終的な答えにたどり着けます。

![キューの動き.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436205/beebf019-c105-ac6d-232a-e570eb1b4438.gif)

## プログラムの欠損部分を補う問題
サンプル問題の問2と問7を見てみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436205/21e4322f-6667-f8dc-3636-3025a7f4d9f7.png)
（出典：基本情報技術者試験（科目B試験）　サンプル問題セット）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436205/94e8462d-4c76-b779-70e4-031d7ad694d1.png)
（出典：基本情報技術者試験（科目B試験）　サンプル問題セット）

科目Bのプログラムを補完する問題では、およそ以下のように大別できます。
- 与えられた仕様を網羅的に満たすようプログラムの個所を補う問題(上記の問2など)
- 仕様と等価な機能をプログラム表現で実現する問題(上記の問7など)

### 仕様を網羅的に満たすようプログラムの個所を補う問題
前者については、forなどの繰り返し処理やifを用いた分岐処理を用いて機能要件を過不足なく満たす問題です。
この問題の必勝パターンとしては、**想定されているパターンの具体例を当てはめてすべてを満たす選択肢を選ぶ**ことが挙げられます。

問2の例だと以下のようにパターンを定められます。

|パターン|具体的な値|戻り値|
|---|---|---|
|3で割り切れて5で割り切れない場合|3|3で割り切れる|
|5で割り切れて3で割り切れない場合|5|5で割り切れる|
|3と5で割り切れる場合|15|3と5で割り切れる|

上記のように具体例を引数として当てはめて机上でシミュレーションしてみると、プログラムが正しく動くかわかります。
問2の例だと、条件分岐とパターンがそれぞれ三つあることから、パターンと条件が一対一で対応しそうですね。
上記の具体例を順番に当てはめてみましょう。

"3で割り切れて5で割り切れない場合 (num <- 3)"を(a)が満たすと仮定すると、それを満たすのは解答例の中では（ア）（イ）のみです。次に、"5で割り切れて3で割り切れない場合 (num <- 5)"を(b)が満たすとすると、選択肢は（イ）のみになります。
しかし、それでは"3と5で割り切れる場合 (num <- 15)"では(a)の時点で条件が成立するため問題に反してしまいます。
そして、これは(a)が"5で割り切れて3で割り切れない場合 (num <- 5)"でも同様に成り立ちそうです。
このことから、最初の条件分岐に入るのは"3と5で割り切れる場合 (num <- 15)"の場合のみになるため、答えは（ウ）と定まります。

### 仕様と等価な機能をプログラム表現で実現する問題
問7を見てみましょう。
階乗とは、1からある自然数までのすべての数字を掛け合わせた値です。
つまり、以下の値を返す関数が求められます。
```
factorial(整数型: n) = 1 * 2 * ... * (n - 1) * n
```
上記の構造を満たす実装方法として、繰り返し処理がすぐに思いつきますが、問題の解答群を見るとそれらしきものがありません。

先ほどの問題の解き方と同様に、具体的な数字を当てはめてすべて満たすような選択肢を探してみましょう。
今回だと、自然数nは無限にパターンが存在します。この場合は、定義域の中でも計算しやすいパターンから当てはめていって徐々に選択肢を削る方法が無難かと思われます。

今回の場合、階乗計算なので、1から徐々にパターンを広げていくのがよさそうですね。

```
factorial(1) = 1
factorial(2) = 2
factorial(3) = 6
factorial(4) = 24
...
```

`factorial(1) = 1`を満たすのは解答群の中では（イ）（ウ）（オ）（カ）です。
`factorial(2) = 2`を満たすのは、上記のうち（オ）（カ）だけです。
`factorial(3) = 6`を満たすのは、上記のうち（カ）となります。

上記のことから、答えは（カ）と求められます。

このように、具体的な数値を当てはめていくことで確実に答えが求められるので、わからない問題があればまずは愚直に数値を当てはめることを試してほしいです。

## 配列の開始位置に注意しておく
サンプル問題では、**配列の開始位置が1となっています**ので本番でもぜひ注意してください。
普段からプログラムを組むのに慣れていると、つい配列の初期位置を0で考えてしまいますが、それだと間違った答えになってしまう恐れがあります。

# 最後に
基本情報技術者試験の勉強は、さらにその上にある応用情報技術者や高度情報技術者試験にも活かすことができます。
ここでしっかり勉強して土台を固めておけば、更なるステップアップに繋がると思うので是非頑張ってほしいです！