11月4日の学び②

長いので終わらなかった。続きはまた今度。

プロセステーブル(プロセス制御ブロック)

Kernelがプロセスの状態を管理するデータ構造

プロセスの生成

  • あるプロセス上で別のプロセスを実行すると必ず親子関係が生じる
  • CLIコマンドを実行すると端末(bash)が親プロセスとなり、実行されるコマンドが子プロセスとなる

親プロセスから子プロセスへの変数の引き渡し

  • ここではあくまでも変数の引き渡し
  • シェル変数では子プロセスは参照できないが、環境変数ならば子プロセスは参照できる

シグナルを用いたプロセス間通信

  • 任意のプロセス間ではシグナルを用いてイベントの発生を通信できる
  • あくまでのイベントの発生であってTCP/IP通信のように任意の信号ではない
  • シグナルの送信をkill、シグナルの受信はtrapと呼ぶ
  • シグナル一覧は"kill -l"コマンドで確認できる
  • killはプロセスを殺すわけではない。(シグナルを省略すると殺すが。)
$ kill -l
 1) SIGHUP   2) SIGINT   3) SIGQUIT  4) SIGILL
 5) SIGTRAP  6) SIGABRT  7) SIGEMT   8) SIGFPE
 9) SIGKILL 10) SIGBUS  11) SIGSEGV 12) SIGSYS
13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGURG
17) SIGSTOP 18) SIGTSTP 19) SIGCONT 20) SIGCHLD
21) SIGTTIN 22) SIGTTOU 23) SIGIO   24) SIGXCPU
25) SIGXFSZ 26) SIGVTALRM   27) SIGPROF 28) SIGWINCH
29) SIGINFO 30) SIGUSR1 31) SIGUSR2

ログインシェル

  • ログインした際に実行されるシェル
  • つまりログインシェルは対話型のアプリケーションの一つであり起動時に自動で実行される。
  • シェルはログイン直後から動き出す
  • 2つ以上のシェルを同時に使えない(1度に使えるのは1つだけ)
  • 使うシェルを途中で変えることができる

関連

blog.a-know.me shellscript.sunone.me language-and-engineering.hatenablog.jp

11月4日の学び

  • デザインパターンでは継承においてメソッドのIFが共通化されているのが大きい
  • 逆にいうとメソッドのIFを共通化できない場合だと単に処理の共通化可能くらいしかメリットがない

Compositeパターン

  • フォルダ&ディレクトリのような再帰的構造に利用される
  • 継承するときにフォルダもディレクトリも共通のIFを持っているところがポイント
  • GUIなどでよくあるパターンらしい

Strategyパターン

  • 処理の実装を取り替え可能にしただけ
  • 単なる関数オブジェクトでは?という声あり

11月3日の学び②

移譲

  • サブクラスが機能拡張する際に、サブクラス内でのオーバロードや新規メソッドの追加ではなく、引数として渡されたクラスを用いること。
  • 早い話が丸投げ
  • 自分では手を動かさずに外からきた人にやってもらう
  • メソッドとしては持っているが自分ではやらない。

11月3日の学び

ファイルシステムの役割

当然だが新しい物理的な記憶装置が出現するとそれに対応したファイルシステムを利用する必要がある。

  • 端的にいうと物理的な記憶装置を抽象化したレイヤーを提供する
  • ファイルへのインタフェースを提供(ファイルの命名・フォルダ/ディレクトリの作成・リンクの作成)
  • 実体としてのファイルが記憶装置のどこに存在するかは意識する必要がない
  • SSDやHDDやオンラインストレージなどの)物理的な記憶装置の差分を吸収すること
  • 永続化時に「パフォーマンス」「信頼性」「一貫性」を担保できること

Visitorパターン

  • パターンとしてはthisを用いて相互参照していることが特徴。
  • でも使うことあるのか??

Decoratorパターン

オブジェクト指向の原則

  • 拡張については開いていて修正に関しては閉じていること
  • クラスの拡張はOKだが、拡張に伴って既存クラスを修正が発生するのはNG

11月2日の学び

Stacktrace

例外のthrow箇所で文字列を引数に与えることで、スタックトレース時に例外の発生状況を確認できる。

       if (Objects.isNull(nextState)) {
            throw new NextStateException("Current State is " + name + ". " + "Next Character is " + currentString.substring(1) + ". ");
        } else {
            nextState.currentString = currentString.substring(1);
            return nextState.transitState();
        }
public class DFA extends Automaton{

    public DFA(StateSet Q) {
        super(Q);
    }

    public void isAccept(String inputString) {

        q0.currentString = inputString;

        try {
            System.out.println(q0.transitState());
        } catch (NextStateException e) {
            e.printStackTrace();
        }
    }

}

例外発生時の指針

  • どんな場合でも通知は必須。握りつぶしはダメゼッタイ!
  • 必ず例外安全なメソッドを用いる。
  • 回復可能な場合(DBへの接続失敗など)は通知して例外発生前の状態に戻す。
  • 回復不可能な場合(起動時に必要なconfigファイルが見つからない場合など)は通知してプロセス自体を終了する(起動自体を失敗させる)。

検査例外と実行時例外

throwかthrowsかやcatchの有無ではなく継承元が異なる。検査例外はExceptionを継承し実行時例外はRuntimeExceptionを継承する。

11月1日の学び(その③)

すっごい基本だけどthrowとthrowsの違いがわからなかった。。。

Javaの例外

  • try/catch:自身の中で例外を処理する
  • throw:例外を明示的に発生させる
  • throws:発生した例外を呼び出し元に通知する

サンプル

以下のようにcatch内で例外を発生させる場合もある。この場合発生した例外は呼び出し元に波及する。

  public void rethrowException(String exceptionName) throws Exception {
    try {
      if (exceptionName.equals("First")) {
        throw new FirstException();
      } else {
        throw new SecondException();
      }
    } catch (Exception e) {
      throw e;
    }

11月1日の学び(その②)

例外処理は真剣に考えると凄く難しい(そして面白い)。

例外処理の目的

  • 例外の回復
  • 例外の通知

例外の回復

  • 例えばDBのにアクセスできない場合にリトライするなど。
  • そもそも回復できるという保証はない。
  • その場合は呼び出し元に通知する。

例外の通知

  • 呼び出し側で例外の通知を受けた場合は、例外が発生する前にロールバックするのが望ましい。
  • その前提条件として、例外を通知する側が保証するべき条件が存在する。
  • それを例外安全と呼ぶ。

例外安全の保証レベル

上から順に強くなる。基本保証が満たされない場合は例外安全ではない。この場合例外発生時に何がおこるか制御不能となるため、その処理自体の利用をやめるべき

  • 基本保証:安全なソフトウェアを作るため(最低限満たすべきレベル)
  • 強い保証:例外回復するため
  • no-fail保証:言語や機構の要求されるため

基本保証

  • 例外が発生した場合に「オブジェクトの内部状態の整合性が保たれる」「オブジェクト内でリソースリーク(プログラムが割り当てたリソースを解放していない状態)が発生しないことを保証する
  • 例えばインスタンスの生成に失敗した際にメモリリークが起きないことなど
  • 基本保証だけでは例外発生時に回復(ロールバック)できない

強い保証

  • 例外が発生した場合に「オブジェクトの内部状態は一切変更されない」ことの保証。
  • これは「例外が発生した場合にロールバック可能であること」と同義。 -「例外発生時に副作用が発生しないこと」と同義
  • DBのトランザクション処理と同じ。
  • 強い保証が満たされていれば例外発生時に回復ができる。

no-fail保証

  • 足し算・引き算などのメソッド。
  • 処理が必ず成功することを保証する。
  • IO系の処理が絡むとno-fail保証は満たされない。
  • 言語や機構に要求されるレベルでの話。

www.techscore.com

qiita.com

例外中立

例外発生時に握りつぶしはダメ絶対。