TECH PLAY

アルゴリズム

イベント

マガジン

技術ブログ

はじめに こんにちは。Insight Edgeでデータサイエンティストをしている善之です。 「Pythonで堅牢なコードを書きたいけど、どう設計すればいいんだろう…」 「バリデーション漏れや予期せぬバグに悩まされている…」 「Javaの設計原則は聞いたことあるけど、Pythonでも同じことができるの?」 こんな疑問や課題を持ったことはありませんか? 先日、名著「良いコード/悪いコードで学ぶ設計入門」を読んで、その設計原則に感銘を受けました。 しかし、この書籍はサンプルコードがJavaで書かれており、Pythonでどう実装すればいいか悩みました。 そこで実際のプロジェクトで、これらの原則をPydanticを使ってPythonで実装する工夫を行ったところ、非常に効果的だったため、そのノウハウをご紹介します。 本記事は、Pythonでより堅牢なコード設計を学びたいエンジニアや、Javaの設計原則をPythonに応用したい方に向けた内容となっています。 なぜこの設計原則が重要か:実践で得たメリット 実際にこの設計原則をプロジェクトで適用した結果、以下のような具体的なメリットが得られました。 コードの安全性・堅牢性の向上 バリデーション漏れの防止 : 不正な値の混入による想定外の動作を防げた 予期せぬバグの防止 : 一度正しく設定した値が想定外に書き換わることがなく、安全にコードを書けた 開発生産性の向上 可読性の向上 : どこに何の処理があるか分かりやすく、ロジックの重複も防ぎやすい チーム開発の効率化 : クラス設計を事前にドキュメント化して共有することで、実装前に設計レビューができ、手戻りが少ない 以降では、これらのメリットを実現するための具体的な実装方法を解説します。 目次 実装した主要な設計原則 1. カプセル化:Pydanticを活用した堅牢なデータモデル 2. 不変(イミュータブル)の活用:frozenで安全性を高める 3. Nullを返さない、渡さない、代入しない 4. 条件分岐におけるInterfaceの活用:ポリモーフィズムと委譲 5. 実装して得られた実践的なメリット まとめ 実装した主要な設計原則 書籍で紹介されていた以下の設計原則を、Pythonで実装しました。 カプセル化 (バリデーション、ロジックのカプセル化) 不変(イミュータブル)の活用 Nullを返さない、渡さない、代入しない 条件分岐におけるInterfaceの活用 (ポリモーフィズムと委譲) それぞれについて、Pythonでどのように実装したかを具体例とともに解説していきます。 具体例では、書籍と同様にRPGの実装を想定したサンプルコードを用います。 1. カプセル化:Pydanticを活用した堅牢なデータモデル 書籍での原則 書籍では、以下のようなカプセル化の重要性が説かれていました。 コンストラクタで確実に正常値を設定する(バリデーションを必ず入れる) インスタンス変数の操作はクラス内のメソッドで行う(ロジックのカプセル化) データとそれを操作するロジックを同じクラスに配置 BaseModelとRootModelの使い分け Pythonでこの原則を適用するには、Pydanticというライブラリが便利です。 Pydanticでは、 BaseModel と RootModel を使い分けることで、カプセル化を実現できます。 BaseModel : 複数の属性を持つクラス 例: Member (パーティメンバー)、 Equipment (装備) RootModel : 単一の値を持つクラス(値クラス) 例: MemberId 、 MemberName 、 HitPoint メリット: model_dump() で "member_id": "M001" のように自然な形式で出力される RootModelを使わない場合: "member_id": {"value": "M001"} という冗長な形式になってしまう バリデーションの実装 Pydanticでは、 field_validator と model_validator を使ってバリデーションを実装します。 field_validator:単一フィールドのバリデーション 単一フィールドの値をチェックする際に使います。 class MemberName (RootModel[ str ]): """メンバー名""" root: str model_config = ConfigDict(frozen= True ) @ field_validator ( "root" ) @ classmethod def validate_name_length (cls, v: str ) -> str : """名前の長さをチェック""" if not v.strip(): raise ValueError ( "メンバー名は必須です" ) if len (v) > 20 : raise ValueError ( "メンバー名は20文字以内にしてください" ) return v class Job (RootModel[ str ]): """職業""" root: str model_config = ConfigDict(frozen= True ) @ field_validator ( "root" ) @ classmethod def validate_job (cls, v: str ) -> str : """職業の種類をチェック""" valid_jobs = { "Warrior" , "Mage" , "Rogue" } if v not in valid_jobs: raise ValueError (f "職業は{valid_jobs}のいずれかを指定してください" ) return v model_validator:クラスメンバ間の整合性チェック 複数のフィールド間の関係性をチェックする際に使います。 例えば、「現在HPは最大HPを超えてはいけない」といった制約を実装できます。 class HitPoint (RootModel[ int ]): """HP""" root: int model_config = ConfigDict(frozen= True ) class Member (BaseModel): """パーティメンバー""" name: MemberName job: Job current_hp: HitPoint max_hp: HitPoint model_config = ConfigDict(frozen= True ) @ model_validator (mode= "after" ) def validate_hp_constraint (self) -> Self: """現在HPが最大HPを超えないことをチェック""" if self.current_hp.root > self.max_hp.root: raise ValueError ( "現在HPは最大HPを超えることはできません" ) return self field_validatorとmodel_validatorを使うメリット: init で実装すれば良いのでは?と思われるかもしれませんが、 field_validatorとmodel_validatorを使うことで以下のメリットがあります。 バリデーションロジックの分離と再利用性が高まる Pydanticの ValidationError で統一的なエラー処理ができる JSON schema生成や自動ドキュメント化といったエコシステムとの統合 __init__ に全て書くと可読性が低下するが、デコレータで宣言的に記述できる ロジックのカプセル化 データを持つクラスに、そのデータを操作するメソッドも配置することで、ロジックのカプセル化を実現します。 class Job (RootModel[ str ]): """職業(Warrior, Mage, Rogueのいずれか)""" root: str model_config = ConfigDict(frozen= True ) @ field_validator ( "root" ) @ classmethod def validate_value (cls, v: str ) -> str : valid_jobs = { "Warrior" , "Mage" , "Rogue" } if v not in valid_jobs: raise ValueError (f "職業は{valid_jobs}のいずれかを指定してください" ) return v def can_use_magic (self) -> bool : """魔法を使える職業かどうかを判定する""" return self.root == "Mage" def can_equip_heavy_armor (self) -> bool : """重装備を装着できる職業かどうかを判定する""" return self.root == "Warrior" class HitPoint (RootModel[ int ]): """HP""" root: int model_config = ConfigDict(frozen= True ) def is_critical (self, max_hp: "HitPoint" ) -> bool : """HPが危機的状態(最大HPの30%以下)かどうかを判定する""" return self.root <= max_hp.root * 0.3 このように、 Job クラスに職業に関する判定メソッドを持たせることで、ロジックが散らばらず、可読性が高まります。 値クラスの徹底 全ての値をクラス化することで、型安全性とバリデーションの一元化を実現します。 例: str ではなく MemberId 、 MemberName 、 ItemName など 例: int ではなく HitPoint 、 MagicPoint 、 AttackPower など 例: bool ではなく IsAlive 、 CanFly 、 IsEquipped など プリミティブ型をそのまま使うと、どの値に対してもバリデーションが必要になり、漏れが発生しやすくなります。 値クラスを使うことで、その値を使う全ての箇所でバリデーションが保証されます。 2. 不変(イミュータブル)の活用:frozenで安全性を高める 書籍での原則 書籍では、イミュータブルな設計の重要性が説かれていました。 再代入はしない オブジェクトの状態を変更せず、新しいオブジェクトを返す 予期せぬ副作用を防ぐ frozenによる基本的なイミュータブル化 Pydanticでは、 model_config = ConfigDict(frozen=True) を設定することで、インスタンス生成後の属性変更を禁止できます。 class MemberName (RootModel[ str ]): """メンバー名""" root: str model_config = ConfigDict(frozen= True ) # これでイミュータブルになる Pythonにはfinal修飾子がないことへの対処 Javaの final に相当する機能がPythonには存在しません。 typing.Final は型ヒントのみで、実行時には強制されないため、 frozen=True を使ってイミュータブル性を確保します。 コレクション型のイミュータブル化 listではなくtupleを使用 list はミュータブルなので、 tuple を使うことでイミュータブル性を確保します。 from types import MappingProxyType class MemberName (RootModel[ str ]): """メンバー名""" root: str model_config = ConfigDict(frozen= True ) class Party (RootModel[ tuple [MemberName, ...]]): """パーティメンバーの集合""" root: tuple [MemberName, ...] = () model_config = ConfigDict(frozen= True ) def add_member (self, new_member: MemberName) -> "Party" : """新しいメンバーを追加した新インスタンスを返す(Immutable)""" if len (self.root) >= 4 : raise ValueError ( "パーティは最大4人までです" ) return self.model_copy(update={ "root" : self.root + (new_member,)}) def __contains__ (self, member: MemberName) -> bool : """指定されたメンバーがパーティに含まれているかチェック""" return member in self.root このように、 add_member メソッドでは元のオブジェクトを変更せず、新しい Party インスタンスを返します。 dictではなくMappingProxyTypeを使用 dict はミュータブルなので、読み取り専用の MappingProxyType を使用することで、外部からの変更を防ぐことができます。 model_copyによるイミュータブルなオブジェクトの更新 frozen=True のオブジェクトは直接変更できないため、値を変更するメソッドをクラス内に実装します。 メソッド内で model_copy(update={...}) を使い、新しいインスタンスを返すことで、元のオブジェクトは変更されず、安全に状態を更新できます。 class Member (BaseModel): """パーティメンバー""" name: MemberName job: Job level: Level current_hp: HitPoint max_hp: HitPoint model_config = ConfigDict(frozen= True ) def recover_hp (self, recovery_amount: int ) -> "Member" : """HPを回復した新しいインスタンスを返す(Immutable)""" new_hp = min (self.current_hp.root + recovery_amount, self.max_hp.root) return self.model_copy(update={ "current_hp" : HitPoint(new_hp)}) # 使用例 injured_warrior = Member( name=MemberName( "アーサー" ), job=Job( "Warrior" ), level=Level( 25 ), current_hp=HitPoint( 30 ), max_hp=HitPoint( 100 ) ) # HPを回復(クラスのメソッドを通じて操作) healed_warrior = injured_warrior.recover_hp( 70 ) print (f "元のメンバー: HP {injured_warrior.current_hp.root}" ) # 30 print (f "回復後: HP {healed_warrior.current_hp.root}" ) # 100 このように、クラス内のメソッドを通じて操作を行うことで、ロジックのカプセル化とイミュータブル性の両方を実現できます。 3. Nullを返さない、渡さない、代入しない 書籍での原則 書籍では、 null を避ける重要性が説かれていました。 null は予期せぬエラーの原因となる null チェックの漏れを防ぐ 代わりに「空の状態を表すオブジェクト」を使う EMPTYパターン(Null Objectパターン) Javaでは static final で空のインスタンスを定義しますが、 今回Pythonで実装するにあたり @classmethod で empty() ファクトリメソッドを提供することにしました。 class ItemName (RootModel[ str ]): """アイテム名""" root: str model_config = ConfigDict(frozen= True ) @ classmethod def empty (cls) -> "ItemName" : """空のItemNameを返す""" return cls( "" ) def __bool__ (self) -> bool : """ItemNameが空かどうかを判定する""" return bool (self.root.strip()) class MagicPoint (RootModel[ int ]): """MP""" root: int model_config = ConfigDict(frozen= True ) @ classmethod def empty (cls) -> "MagicPoint" : """空のMagicPointを返す(MP=0)""" return cls( 0 ) def __bool__ (self) -> bool : """MPが存在するかどうかを判定する""" return self.root > 0 型ごとの空の表現: 数値の場合: None の代わりに値が 0 のインスタンスを返す 文字列の場合: None の代わりに空文字 "" のインスタンスを返す コレクションの場合: None の代わりに空のtuple () のインスタンスを返す bool メソッドによる存在判定 null 判定の代わりに、 __bool__(self) メソッドで中身の値が存在するかを判定します。 これにより、Pythonらしい if xxx: という記述で中身があるかの判定が可能になります。 # 使用例 item_name = ItemName.empty() if item_name: # アイテムが存在する場合の処理 print (f "アイテム: {item_name.root}" ) else : # アイテムが存在しない場合の処理 print ( "アイテムなし" ) 4. 条件分岐におけるInterfaceの活用:ポリモーフィズムと委譲 書籍での原則 書籍では、条件分岐をInterfaceで置き換える設計が推奨されていました。 条件分岐(if/switch文)を使わず、Interfaceとポリモーフィズムで表現 「委譲」を使ってロジックを分離 新しい条件追加時にコード修正が最小限になる(Open-Closed Principle) ABCを使った抽象基底クラス Pythonには interface キーワードがないため、 abc.ABC を使用して抽象基底クラスを定義します。 from abc import ABC, abstractmethod class EquipmentCondition (ABC): """装備条件の抽象クラス""" @ abstractmethod def can_equip (self, member: "Member" ) -> bool : """メンバーが装備可能かを判定する""" pass @ abstractmethod def get_description (self) -> str : """条件の説明を取得する""" pass 具体的な条件クラスの実装 抽象クラスを継承して、具体的な条件を実装します。 class Level (RootModel[ int ]): """レベル""" root: int model_config = ConfigDict(frozen= True ) class JobCondition (BaseModel, EquipmentCondition): """職業に基づく装備条件""" required_job: Job model_config = ConfigDict(frozen= True ) def can_equip (self, member: "Member" ) -> bool : """指定された職業のメンバーのみ装備可能""" return member.job.root == self.required_job.root def get_description (self) -> str : return f "{self.required_job.root}専用" class LevelCondition (BaseModel, EquipmentCondition): """レベルに基づく装備条件""" required_level: Level model_config = ConfigDict(frozen= True ) def can_equip (self, member: "Member" ) -> bool : """指定されたレベル以上のメンバーのみ装備可能""" return member.level.root >= self.required_level.root def get_description (self) -> str : return f "レベル{self.required_level.root}以上" このように、 JobCondition と LevelCondition という異なる条件をそれぞれ別のクラスで表現します。 条件の使用例:委譲パターン 装備アイテムクラスが装備条件を保持し、実行時に適切な条件クラスのメソッドが呼ばれます(ポリモーフィズム)。 条件分岐を書かずに、委譲で処理を実現できます。 class Equipment (BaseModel): """装備アイテム""" name: ItemName conditions: tuple [EquipmentCondition, ...] model_config = ConfigDict(frozen= True ) def can_be_equipped_by (self, member: "Member" ) -> bool : """指定されたメンバーが装備可能かを判定""" # 全ての条件を満たす必要がある return all (condition.can_equip(member) for condition in self.conditions) def get_requirement_text (self) -> str : """装備条件の説明文を取得""" if not self.conditions: return "誰でも装備可能" return "、" .join(cond.get_description() for cond in self.conditions) # 使用例 excalibur = Equipment( name=ItemName( "エクスカリバー" ), conditions=( JobCondition(required_job=Job( "Warrior" )), LevelCondition(required_level=Level( 20 )) ) ) warrior = Member( name=MemberName( "アーサー" ), job=Job( "Warrior" ), level=Level( 25 ), current_hp=HitPoint( 100 ), max_hp=HitPoint( 100 ) ) # 条件分岐を書かずに、委譲で処理 if excalibur.can_be_equipped_by(warrior): print (f "{warrior.name.root}は{excalibur.name.root}を装備できます" ) この実装の優れている点は、新しい条件(例えば StrengthCondition )を追加する際に、既存のコードを変更する必要がないことです。 新しい条件クラスを作るだけで、 Equipment クラスはそのまま動作します。 5. 実装して得られた実践的なメリット 実際にこの設計原則をプロジェクトで適用した結果、以下のようなメリットが得られました。 コードの安全性・堅牢性の向上 バリデーションによる予期せぬ挙動の防止 バリデーションをしっかり行うことで、不正な値の混入による想定外の動作を防げました。 特に、複数人で開発する際に、他のメンバーが誤った値を渡してもバリデーションで防げたため、開発初期にエラーが発生し、デバッグが容易でした。 実際のプロジェクトではあるアルゴリズムを実装したのですが、アルゴリズムの予期せぬ挙動を防ぐことができました。 イミュータブルによる安全性の向上 イミュータブルなので、バリデーションで正しく入った値を後から勝手に書き換えられない安心感がありました。 複数箇所でオブジェクトを参照しても、意図しない変更による副作用がなく、安全にコードを書けました。 値クラスによるバリデーション漏れの防止 全ての値をクラス化(値クラス)したことで、バリデーションに漏れがありませんでした。 プリミティブ型をそのまま使うと、バリデーション忘れが発生しやすいですが、値クラスを使うことで型エラーで早期に問題を発見できました。 一方で、これによりクラス数が膨大になってしまうと思われるかもしれません。 実際に、途中参加したメンバーからは「クラス数が多くて最初は面食らった」という声もありました。 しかし、同じメンバーも「1つ1つのクラスがシンプルな作りになっているため慣れるのは早かった」と述べており、学習コストはそれほど高くありませんでした。 また、1つ1つのクラスにバリデーションが集約されることで可読性が向上し、コードを読む際の認知負荷が軽減されるメリットは、クラス数が増えるデメリットを上回ると考えています。 開発生産性の向上 カプセル化による可読性の向上 クラス内にそのクラスの値に関連する操作の関数が入るので、可読性が高くなりました。 どこに何の処理があるか分かりやすく、ロジックの重複も防ぎやすくなりました。 インターフェース設計による要件の明確化とチーム開発の効率化 まずはインターフェースのみ設計したのち、MkDocsで自動ドキュメント化してメンバーに共有することで、データ型やバリデーション条件など、必要な要件が明確に伝わりました。 実装前に設計レビューができたため、手戻りが少なく、チーム全体の開発効率が向上しました。 まとめ 今回は、Javaベースの設計原則をPythonでいかに実現するかについて、実装例とともにご紹介しました。 Pydanticを活用することで、 frozen=True 、 RootModel 、 field_validator 、 model_validator といった強力な機能を使い、Javaベースの設計原則をPythonでも十分に実現できました。 実際のプロジェクトで適用した結果、バリデーション漏れの防止、予期せぬ副作用の回避、可読性の向上など、多くのメリットが得られました。 Pythonで堅牢なコードを書きたい方や、設計原則に興味がある方の参考になれば幸いです。 関連記事 設計原則については弊社のテックブログでも過去に取り上げていますので、以下の記事も是非ご参照ください。 生成AIアプリのクリーンアーキテクチャを考える - カプセル化や抽象化をアプリケーション全体のアーキテクチャに適用する方法を解説しています FastAPI,Pydantic,AWS DynamoDBを組み合わせた型安全なAPI構築方法について - Pydanticを実際のAPI開発で活用する実践例を紹介しています AdhocなPythonコードをProduction-readyにするために心掛けていること - 型情報の付与やバリデーションを含む、実運用を見据えたPythonコード品質向上の手法を解説しています 参考文献: 「良いコード/悪いコードで学ぶ設計入門」(仙塲大也 著、技術評論社) Pydantic公式ドキュメント: https://docs.pydantic.dev/ Python公式ドキュメント(abc module): https://docs.python.org/3/library/abc.html
C++のコンテナで条件を満たす要素があるか判定する際、for文の代わりに`std::any_of`アルゴリズムを使うとコードが簡潔で分かりやすくなります。本記事では、具体的なコード例を交えて`std::any_of`の利点と活用法を紹介します。
キャリアプロダクト開発部の森 @jiskanulo です。 私ごとですが今年で45歳、WEBサービスの開発歴は20年以上になります。世間的にはベテランエンジニアとかシニアエンジニアとかと称される類だと自認しています。 そんな私ですが2026年1月に基本情報技術者試験を受験して合格しました。 この記事は、ベテランエンジニアが基本情報技術者試験をスキル棚卸しツールとして活用した体験と、受験しなくても使えるセルフチェックの方法を紹介します。 www.ipa.go.jp 受験の動機 結果 得意と苦手が可視化された 得意だった領域 苦手だった領域 得意と苦手のコントラストが意味するもの 試験範囲でスキルを棚卸しする方法 受験のTips CBT受験の雰囲気 集中力の維持に課題 まとめ 受験の動機 受験したきっかけは昨今のAIエージェントを前提とした開発手法の変化です。 ファインディではAIエージェントの導入・検証を積極的に行っています。 私もDevin, GitHub Copilot Chat, Cline, Claude Codeなどさまざまなツールやサービスを日々の開発業務に導入すべく検証していました。 2025年6月頃からClaude Codeを本格的に使用しはじめ、2026年3月現在では私自身が手でコードを書くことは全くなくなりました。 昨今のAIエージェントが主となり開発を進める体制では、AIエージェントへ適切な指示を出す力、AIエージェントからの提案を判断し承認・修正するための力が求められます。 この力をつけるための基礎知識として、基本情報技術者試験の内容はちょうどよいと感じています。 また、2025年末に開発部で「基本情報技術者試験の合格を目指しましょう」という方針も出たこともあり、社内のメンバーが続々と受験・合格している流れに乗りました。 受験理由をもう一つ挙げると、実は基本情報技術者試験を20年ほど前に受験して不合格になっており再挑戦をしないままでした。 さらに後年に応用情報技術者試験を受験し合格しているのですが、応用情報は持っているのに基本情報は持っていないというチグハグ感を解消したかったのです。 近いうちにデータベーススペシャリスト試験を受けようと考えていたところ、2026年度からCBT(コンピュータベースの試験)方式に移行するという情報があり、CBTの雰囲気を先に体験しておきたいという思いもありました。 ただデータベーススペシャリスト試験の実施そのものが2026年中は不明瞭な状況です。動向を注視しつつ、申し込みが再開されたらすぐエントリーしたいですね。 www.ipa.go.jp 結果 科目Aは705点、科目Bは680点となんとか合格できました。もう少し余裕を持って合格したかったのですが、そこは今後の伸びしろとします。 得意と苦手が可視化された 受験して最も収穫だったのは、自分のスキルの輪郭がはっきり見えたことです。 得意だった領域 計算問題やコードリーディング、データベース正規化や稼働率計算などの問題はスムーズに解けました。 日常業務でコードを書き、レビューし、設計・運用を考えることを毎日やっているので、実務経験がそのまま得点に結びつきました。 過去問の模擬試験でもこれらの分野は正答率が高く、特別な対策をしなくても安定して解ける状態でした。 苦手だった領域 一方、会計管理や財務指標に関する問題には苦戦しました。損益分岐点、ROI、減価償却といったテーマは過去問を解いていても正答率が目に見えて低い分野でした。 振り返ってみると、日々の開発業務で財務指標を意識する場面はほとんどありませんでした。 業務で触れない領域は経験年数に関係なく穴のまま残っている。この気づきが、受験して得た最大の収穫でした。 得意と苦手のコントラストが意味するもの この経験から見えたことは、エンジニアのスキルは実務でカバーしている範囲には自然と強くなれるが、逆に触れていない範囲は何年経っても盲点のままだということです。 基本情報技術者試験の出題範囲はITエンジニアの基礎知識を広くカバーしています。 だからこそ、受験すると自分のスキルマップの中で「どこが埋まっていて、どこが空白か」が浮き彫りになります。 試験のための勉強がすぐにサービス開発に活かせるかというとそうでもないのですが、自分の基礎知識の全体像を把握するにはちょうどいい粒度だと感じました。 試験範囲でスキルを棚卸しする方法 受験するにあたり、基本情報技術者試験ドットコムに大変お世話になりました。 www.fe-siken.com 私の場合は1日30分、20日間ほどで合計600問を回答しました。無料サービスの範囲でも十分に過去問を試すことができますし、有料のメンバー登録をすると学習の記録管理がしやすくなります。 スキル棚卸しをするために、まず科目Aの過去問を解いてみてください。 分野ごとの正答率が記録されるので、自分がどの分野に強く、どの分野に穴があるかが数値で可視化されます。 参考として、基本情報技術者試験の科目A出題範囲をもとにしたセルフチェック表を載せておきます。自分が「得意」「苦手」「触れたことがない」のどれに当たるか振り返ってみてください。 分野 自己評価(筆者の例) 基礎理論(離散数学、情報理論等) 得意 アルゴリズムとプログラミング 得意 コンピュータ構成要素 得意 システム構成要素 得意 ソフトウェア 得意 ハードウェア 苦手 データベース 得意 ネットワーク 苦手 セキュリティ 得意 マネジメント(プロジェクト・サービス) 苦手 ストラテジ(経営戦略・法務) 苦手 表のとおり、実務で日常的に使う分野は得意、そうでない分野は苦手という傾向がはっきり出ました。 正答率が安定して高い分野は実務でカバーできている基礎知識。低い分野やまったく分からない分野は、業務で触れていない盲点です。「知っているつもりだったが正確には理解できていなかった」という曖昧な領域も見つかるかもしれません。 受験のTips CBT受験の雰囲気 当日午後に受験会場に着くと、試験開始時刻前でも受験を始めてよいと案内されました。 パソコンに向かう前に持ち物検査を終えて着席。 キーボードはログイン時にしか使わず、試験中はマウス操作のみ。紙とペンは貸してもらい、筆算やコードのトレースをしながら回答しました。 回答完了ボタンを押すとすぐに得点が表示され、合否をその場で確認できました。結果待ちのモヤモヤがなかったのは嬉しいポイントでした。 集中力の維持に課題 科目Bの時点で集中力が切れてしまったのが今回の反省点です。 20年前は午前問題のあとに2時間ほどの昼休みがあり、リフレッシュしてから午後問題に臨めました。現在の形式では科目Aのあと10分の休憩で科目Bが始まるため、体力的にも精神的にも消耗した状態で後半戦に入ることになります。 受験する前には十分に体調を整えて臨むことをおすすめします。 まとめ 基本情報技術者試験は、資格取得という目的だけでなく、自分のスキルの得意と苦手を可視化するツールとして活用できました。 スキルを可視化できたこともあり、今年中にデータベーススペシャリスト試験の合格を目指して準備を進めていこうと思います。 みなさんも試験を受けてみてください。受験しなくても、過去問を試すだけでスキルの棚卸しになりますよ。 ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers

動画

書籍