技術とか戦略とか

IT技術者が技術や戦略について書くブログです。

SaaS・PaaS・IaaSの覚え方

クラウドコンピューティングのサービス形態を覚えるための簡単な表を作りました。
 
SaaS・PaaS・IaaSの概要

f:id:akira2kun:20210601004417j:plain

 頭文字を取って「SPI」と覚えると、より覚えやすいかもしれません。
 ちなみに、「SPI」は就職試験で使われる有名な適性試験の名前です。
 
SaaS・PaaS・IaaSでの資源の扱い

f:id:akira2kun:20210601004434j:plain

 
----------------------
 
情報処理技術者試験に関する記事の目次
https://1drv.ms/b/s!AivF3bzWXOzuhG1Xk5hscKYqkLkM

Java:任意の順番でのソート

JavaのCollection型(サブクラスにList型等がある)は、Collections.sortメソッドでソートすることが可能です。
Collections.sortメソッドは、第一引数にソートしたいCollection型のオブジェクト、第二引数にComparator型のオブジェクトを渡します。
第二引数のComparator型のオブジェクトにより、ソート順が決まります。
 
Collections.sortメソッドでは、Comparator型のcompareメソッドを利用してソートを行います。
ソート順を定義するためには、Comparator型を実装したクラスを独自に作成し、compareメソッドをオーバーライドして独自のロジックを記述する必要があります。
compareメソッドの説明は以下です。
https://docs.oracle.com/javase/jp/8/docs/api/java/util/Comparator.html#compare-T-T-
簡単に言うと、compareメソッドの第一引数と第二引数について、戻り値がマイナスの値の場合は「第一引数→第二引数」の順番に並び、戻り値がプラスの値の場合は「第二引数→第一引数」の順番に並びます。
 
これを利用して、任意の順番でソートを行うサンプルが以下になります。
 
【サンプルコード】
・MySortMain.java
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class MySortMain {

  public static void main(String[] args) {

    // ソート対象のリストを作成する
    List<String> list = new ArrayList<>();
    list.add("メグリネ ルカ");
    list.add("ハツネ ミク");
    list.add("カガミネ レン");
    list.add("カガミネ リン");

    // ソート(文字コード順)
    Comparator<String> mySort1 = new MySort1();
    Collections.sort(list, mySort1);
    System.out.println("[文字コード順のソート]");
    for (String str : list) {
      System.out.println(str);
    }

    // ソート(独自ソート順)
    Comparator<String> mySort2 = new MySort2();
    Collections.sort(list, mySort2);
    System.out.println("");
    System.out.println("[独自ソート順のソート]");
    for (String str : list) {
      System.out.println(str);
    }

  }

}
 
・MySort1.java
import java.util.Comparator;

// 今回はString型を対象としているが、独自型にも同じ方法で対応できる
public class MySort1 implements Comparator<String> {

    @Override
    public int compare(String o1, String o2) {
      // o1の文字コードからo2の文字コードを減算した値を返すメソッド
      return o1.compareTo(o2);
    }

}
 
・MySort2.java
import java.util.Comparator;

// 今回はString型を対象としているが、独自型にも同じ方法で対応できる
public class MySort2 implements Comparator<String> {

  @Override
  public int compare(String o1, String o2) {
    return mySortOrder(o1) - mySortOrder(o2);
  }

  // 独自のソート順の定義
  public int mySortOrder(String str) {
    if (str.equals("ハツネ ミク")) { return 1; }
    else if (str.equals("カガミネ リン")) { return 2; }
    else if (str.equals("カガミネ レン")) { return 3; }
    else if (str.equals("メグリネ ルカ")) { return 4; }
    else {return 5;}
  }

}
 
【実行結果】
文字コード順のソート]
カガミネ リン
カガミネ レン
ハツネ ミク
メグリネ ルカ

[独自ソート順のソート]
ハツネ ミク
カガミネ リン
カガミネ レン
メグリネ ルカ

java:通常のクラスと匿名クラス(無名クラス)の書き方の比較

以前の記事(https://cyzennt.co.jp/blog/2020/10/16/%e7%84%a1%e5%90%8d%e3%82%af%e3%83%a9%e3%82%b9%e3%81%a8%e3%81%af/)で「通常のクラスと匿名クラスの書き方の比較を見たい」という意見があったので、少し補足を行います。
 
サンプルコードの通り、匿名クラスの場合、クラスに名前を付ける必要が無く、またオブジェクト生成と同時に処理を定義することができます。
これにより、以下のようなメリットがあります。
・記述を簡潔にできる
・使い捨てのクラスを定義でき、使い捨てであるという意図も明確にできる
・(ソースファイル名とクラス名を同じにする場合)管理が容易になる
 
【サンプルコード】
・AnonymousClass.java
public class AnonymousClass {
  private String str = "Hello Class!";
  public String getStr() {
    return str;
  }
  public void print() {
    System.out.println(getStr());
  }
}
 
・AnonymousSubClass.java
// 通常のクラスの定義(クラスの継承)
public class AnonymousSubClass extends AnonymousClass {
  public void print() {
    System.out.println("NonAnonymous:" + getStr());
  }
}
 
・AnonymousInterface.java
public interface AnonymousInterface {
  public void print();
}
 
・AnonymousImplementsClass.java
// 通常のクラスの定義(インターフェースの実装)
public class AnonymousImplementsClass implements AnonymousInterface {
  public void print() {
    System.out.println("NonAnonymous:Hello Interface!");
  }
}
 
・AnonymousMain.java
public class AnonymousMain {
  public static void main(String[] args) {

    // 通常のクラスのオブジェクトの生成(クラスの継承)
    AnonymousClass nac = new AnonymousSubClass();
    nac.print();

    // 匿名クラスの定義とオブジェクト生成(クラスの継承)
    AnonymousClass ac = new AnonymousClass() {
      public void print() {
        System.out.println("Anonymous:" + getStr());
      }
    };
    ac.print();

    // 通常のクラスのオブジェクトの生成(インターフェースの実装)
    AnonymousInterface nai = new AnonymousImplementsClass();
    nai.print();

    // 匿名クラスの定義とオブジェクト生成(インターフェースの実装)
    AnonymousInterface ai = new AnonymousInterface() {
      public void print() {
        System.out.println("Anonymous:Hello Interface!");
      }
    };
    ai.print();
  }
}
 
【実行結果】
NonAnonymous:Hello Class!
Anonymous:Hello Class!
NonAnonymous:Hello Interface!
Anonymous:Hello Interface!

情報処理技術者試験対策「共通鍵暗号方式・公開鍵暗号方式とSSL」

この記事では、暗号化が必要な理由や共通鍵暗号方式・公開鍵暗号方式の概要、SSLの仕組みの概要について書きます。
 
1.暗号化が必要な理由
ノード(端末やサーバ等、他の機器との通信を行う主体を指す)間の通信内容は、Wiresharkのようなパケットキャプチャ(ソフトウェア)で確認することが可能です。
どのような形で確認できるのかは、Googleの画像検索(https://www.google.com/search?q=Wireshark&sxsrf=ALeKk02z0RxYtT7G0O_rVmDxd3LoryWp4g:1615711689095&source=lnms&tbm=isch&biw=1366&bih=657)で調べればイメージがわきやすいと思います。
 
そして、ユーザ/パスワードのような重要な情報を送受信する際も、同じようにパケットキャプチャで通信内容を見ることができてしまいます。
もし、そのような重要な情報が平文(生データ)で送受信されていたとしたら、それはセキュリティ面で重大なリスクとなります。
例えば、ユーザ/パスワードを盗み見た第三者が、なりすましでログインすることができてしまいます。
 
それを防ぐために、「鍵」と呼ばれる通信を行う者同士であらかじめ共有されたデータを使用し、特定のアルゴリズムにより通信するデータを暗号文に変換します。
そうすることで、第三者に通信内容を盗み見られたとしてもその中から重要な情報を取得されるのを防ぐことができます。
「鍵」を持たない第三者が暗号文を見ても内容を理解できない、という所が重要です。
 
2.共通鍵暗号方式・公開鍵暗号方式の仕組み
暗号化の方式は大きく分けて二つあり、「共通鍵暗号方式」と「公開鍵暗号方式」があります。
 
2.1.共通鍵暗号方式
これは、あらかじめ2者間で共有された共通鍵を使用する方式です。
図解すると以下のようになります。

f:id:akira2kun:20210501003619j:plain
 
この方式は、方式が単純であることから暗号化・復号を早く行うことができるのが利点ですが、多くの鍵を用意する必要がでてきてしまう欠点があります。
上記の図の通りなのですが、2者の組み合わせ毎に鍵を用意する必要が出てきてしまうため、n(n-1)/2の分だけ鍵が必要になってしまいます。
(各々のノード(n)は、他の各々のノード(*(n-1))に対して鍵を用意する必要がある。ただし、2者間で別々の鍵を用意する必要はない(/2)。)
 
2.2.公開鍵暗号方式
これは、それぞれの主体が秘密鍵と共有鍵を管理し、通信を行う時に通信相手に共有鍵を渡して通信を行う方式です。
図解すると以下のようになります。

f:id:akira2kun:20210501003636j:plain
 
この方式は、少ない鍵で通信を行うことができる利点がありますが、方式が難しく暗号化・復号を早く行うことができません。
必要な鍵の数は、それぞれの主体が秘密鍵と共有鍵の2つの鍵さえ持っていれば良いので、必要なのは2nの分のみです。
 
3.SSLについて
インターネット上で通信を安全に行う仕組みとして、SSLと呼ばれる仕組みがあります。
SSLは、インターネットプロトコルであるhttpsにも使われています。
(重要な情報を送受信する時にはhttpsを使うべきであると言われたことがあると思いますが、httpsが安全な理由はSSLを使っているからです)
 
SSLでは、先で説明した共通鍵暗号方式と公開鍵暗号方式を利用しています。
また、サーバ証明書を利用するのも特徴です。
サーバ証明書とは、認証局(サーバの正当性を証明する第三者の企業)からサーバに対して付与されるものであり、通信を行うサーバが正当なものである(犯罪等に悪用されることがない)ことを証明するデータです。
仕組みは以下の通りです。

f:id:akira2kun:20210501003653j:plain
 
----------------------
 
情報処理技術者試験に関する記事の目次
https://1drv.ms/b/s!AivF3bzWXOzuhG1Xk5hscKYqkLkM

情報処理技術者試験対策「排他制御・デッドロック」

この記事では、情報処理技術者試験で問われる排他制御デッドロックについて、基礎的なことを書いていきます。
 
排他制御デッドロックを理解する前に、トランザクションについて理解する必要があります。
トランザクションとは、複数の処理をひとまとまりにしたものです。
例えば、出庫時に在庫数を更新するトランザクションは、下記の処理をひとまとまりにすることで実現できます。
・在庫テーブルから在庫量を取得する
・取得した在庫量から出庫した分を差し引く
・差し引いた在庫量を在庫テーブルに反映させる
 
このトランザクションを実行する上で注意が必要なのは、トランザクション実行中に在庫テーブルが更新されないことを保証する必要があることです。
もし、在庫量を取得した後に在庫テーブルが更新されてしまった場合、トランザクションで算出した在庫量でその更新を上書きしてしまいます。
それを防ぐために、トランザクション中で在庫テーブルにロック(排他制御)をかけ、トランザクション実行中に在庫テーブルが更新されないようにします。

f:id:akira2kun:20210501002637j:plain

 
このように更新結果の不整合を防げるのがロックなのですが、デメリットもあります。
複数のトランザクションがロックをかけた場合、複数のトランザクションがお互いにロック待ちの状態となり、トランザクションを終了できないのでロックを解除することもできず、(強制的にトランザクションを終了させるまでの間)永久にトランザクションが終了しなくなることがあります。
このような現象を、デッドロックと呼びます。

f:id:akira2kun:20210501002707j:plain
 
デッドロックを防ぐための代表的な手段として、トランザクションの間でロックする順番を統一するという手段があります。
この手段を用いることで、他のトランザクションが中途半端に進んで中途半端にロックをかけることがなくなるので、デッドロックを防ぐことができるようになります。

f:id:akira2kun:20210501002723j:plain
 
----------------------
 
情報処理技術者試験に関する記事の目次
https://1drv.ms/b/s!AivF3bzWXOzuhG1Xk5hscKYqkLkM

情報処理技術者試験対策「VR・AR」

最近の情報処理技術者試験では、VRとARの違いを知らないと答えられない問題が出題されることがあります。
 
詳しい知名度は以下の通りなのですが、VRという用語に比べて、ARという用語は比較的知名度が低いです。
 
VR認知度は87.6%、ARは34%。『VRビジネス調査報告書2018』が発売 - VR Watch
https://www.watch.impress.co.jp/vr/articles/news/20180124_vrbusiness.html
 
情報処理技術者の試験勉強でARという用語を始めて知ったという方も少なくないかもしれません。
また、このテーマは10年ほど前の情報処理技術者試験では問われなかったテーマなので、昔に受験してそれっきりの方は今でも知らないかもしれません。
 
簡単に言うと、VRとはゴーグル等の機器を装着して仮想現実の中での疑似体験を提供するシステム、ARとは現実世界の中に情報を付与するシステム、という違いがあります。
イメージしやすい例を挙げると、「Pokémon GO」はARです。鳥取砂丘に出向き、スマートフォンのカメラで映し出した砂丘の中にレアポケモンを出現させて、スマートフォン上のスワイプ操作で捕まえる。これがイメージできれば、ARの言葉の意味は一発で覚えられると思います。
 
レガシーなシステムを昔から保守している技術者にとっては関係の無い話に思えるかもしれませんが、レガシーシステムが提供するAPIを通して最新鋭のシステムと連携する、という例は少なくなりません。
将来的にVRやARと連携することもあるかもしれませんので、システムの提案や社外との打ち合わせに備えて、言葉の意味だけでも覚えておいて損はないと思います。
 
----------------------
 
なお、2021年時点では情報処理技術者の出題範囲外だと思いますが、VRやARの他にMRという用語もあるので、こちらも覚えておくと良いでしょう。
MRは、VRとARを組み合わせたようなものです。
現実世界の上に情報が付加されているARとは異なり、VRと同じように機器を通して視覚や触覚による体験を行うことができます。
また、全くの仮想世界での体験となるVRとは異なり、ARと同じように現実世界をベースとした体験となります。
 
----------------------
 
情報処理技術者試験に関する記事の目次
https://1drv.ms/b/s!AivF3bzWXOzuhG1Xk5hscKYqkLkM

情報処理技術者試験対策「静的解析ツール・動的解析ツール」

情報処理技術者試験では、「静的解析ツールとは何か」「動的解析ツールとは何か」を問う問題が出題されます。
この記事では、これらのツールは何か、何のために使うのか、といったことについて簡単に書いていきます。
 
【静的解析ツールの説明】
静的解析ツールとは、実行しない状態でソースコードのチェックを行うツールです。
コンパイル前に、コンパイルエラーや実行時エラーとなる箇所、若しくはエラーになる可能性が高かったり可読性が低下したりする箇所を見つけ、警告を出してくれます。
エラーや可読性低下につながる箇所を最速のタイミングで見つけることができ、また人間によるソースコードレビューと異なり見落としが出ることもないので、静的解析ツールを適切に使うことで品質が向上しやすくなります。
 
EclipseJavaソースコードを書く時に、未使用のインポートや変数が存在する時に黄色の波線が出た経験はないでしょうか?
静的解析ツールは、その機能をよりリッチにしたものと考えて良いです。
Eclipse自体も静的解析ツールの機能を含んでいると考えて良いと思っています)
Javaの場合、「FindBugs」や「SonarQube」といったツールが代表的な静的解析ツールとして挙げられます。
 
【動的解析ツールの説明】
動的解析ツールとは、実行時にプログラムの実行状態を解析するツールです。
変数の内部状態の表示や、プログラムの呼び出し回数・実行時間の計測、プログラムの命令や分岐の網羅率の計測、アサーションチェック(変数状態等が期待結果と一致していることの確認)等を行います。
単純に実行結果を見るだけでは分からない情報を見ることができるので、バグの調査やテストの実施状況確認、テストの実行結果の確認といった作業を効率良く行うことができるようになります。
 
Eclipseデバッグ機能を使うと、各ステップ毎で変数の内部状態の変化を見ることができます。
Eclipseがサポートするこの機能も、動的解析ツールと呼べるものです。
 
----------------------
 
目次
https://1drv.ms/b/s!AivF3bzWXOzuhG1Xk5hscKYqkLkM