プログラミングBlog

2021年2月の振り返り

2121年2月の振り返り

Keep

  • 去年の12月から継続中の土曜日の勉強会(7:00-9:00)
  • AWSクラウドラクティショナー資格の勉強。
  • C#イディオム、定石&パターン。(書籍)
  • BuildUpで学習記録をつけていく。

Problem

  • 仕事での残業が増えた。 月間60h程。
  • 実力不足を痛感 デザインパターン&&イディオムを学ぶ
  • 体重増加。健康診断でおなか周りの注意。激務により運動不足。

Try

2月の学習時間

2月7日~3月5日時点の学習時間
f:id:Tokuty:20210306165821p:plain
Total69h

今後

Problemに関してはほぼ問題が仕事関係なので、継続して学習していき稼働時間を抑えていく。
プログラミングを学ぶ方法の一つとして、個人でのアプリ開発や、githubのソースを見たほうがいいとのアドバイスを頂いてたので、
書籍中心の学習内容から、次のステップに進むべき。
打開策としてなにかしらのアプリを月1以上で作っていきたい。

Java gradleProjectをjarにする。

Eclipsでのjar化の手順書

Projectを右クリック→実行→実行の構成。 f:id:Tokuty:20210306140335p:plain
Gradle Taskを検索して、新規構成を作成。 f:id:Tokuty:20210306140455p:plain
新規構成を検索して、 Gradle Taskの部分にbuildを追加。
作業ディレクトリはjarにしたいプロジェクトを選ぶ。
適用を押す。
f:id:Tokuty:20210306140552p:plain
実行を押すとgradle buildが行われる。 f:id:Tokuty:20210306140737p:plain
完了したら、プロジェクトを右クリック→Windows エクスプローラ―へ移動
f:id:Tokuty:20210306140830p:plain
buildフォルダができているので
C:\githubRepos\Java\SpringSample\sampleProject02\build\libsまで移動。
jarができていたらOKです。
f:id:Tokuty:20210306140927p:plain

C#でオブジェクト指向①

オブジェクト指向の抽象化

目的:朝のルーティンをオブジェクト指向の抽象化を使って実装していく。

まず、実際にコードを書いていく前にルーティーンを考えました。
起床、目覚まし止める、歯磨き、着替え、トイレ、朝ごはん.....etc 書きだしたらきりがないので抽象化してきます。

抽象可とは・・・思考における手法のひとつで、対象から注目すべき要素を重点的に抜き出して他は捨て去る方法である

抽象化 - Wikipedia wiki調べ。

というわけでまとめてみました。

平日の朝のルーティー

起床、準備、出勤

休日の朝のルーティー

起床、準備、まったり


イメージとしては基底クラスにこれらの3つのふるまいを抽象化して、
継承先に実装した処理を書いていく。
なので用意するものは基底クラス、休日クラス、平日クラス
基底クラスに起床、準備、出勤、まったり。 処理の開始メソッド。分岐メソッド。
このような感じでしょうか。
実際に書いていきます。

基底クラス

基底(Base)となるクラスを作成していきます。

  • abstractは継承先で必ず実装する。

  • virtualは継承先で実装するかしないかを選択できる。


出勤とまったりメソッドについては 平日だけど午前休だとか、休日だけどまったりできない日とかあるかもしれないので変更できるようvirtualにしてみました。

さきほどまとめた4つのメソッド 起床、準備、、出勤、まったり

        // 起床
        protected abstract void GetUp();

        // 準備
        protected abstract void Preparation();

        // 出勤
        protected virtual void Commuting()
        {
            Console.WriteLine("出勤します。");
        }

        // まったり
        protected virtual void Relax()
        {
            Console.WriteLine("まったりします。");
        }

これらの共通処理を実行するメソッド を書いていきます。
まずルーティング分岐とルーティンスタートメソッド2種類用意。
後々、ルーティンが増える??昼とか夜とか。。。かもしれないので分岐メソッドも定義してみました。
flgを立てて休日か平日によって処理が変わるようにしています。

分岐メソッド。 処理の開始メソッド。

        /// <summary>
        /// ルーティーン分岐
        /// </summary>
        public static void RoutinWork(bool isFolidayFlg)
        {
            if (isFolidayFlg)
            {
                new HolidayRoutin().Start(isFolidayFlg);
            }
            else
            {
                new WeekdaysRoutin().Start(isFolidayFlg);
            }
        }

        /// <summary>
        /// ルーティーンスタート
        /// </summary>
        public void Start(bool isFolidayFlg)
        {
            // 起床
            GetUp();

            // 準備
            Preparation();

            if (isFolidayFlg)
            {
                // まったり
                Relax();
            }
            else
            {
                // 出勤
                Commuting();
            }
        }

基底クラス

 /// <summary>
    /// ルーティーン基底クラス
    /// </summary>
    public abstract class RoutinWorkBase
    {

        /// <summary>
        /// ルーティーン分岐
        /// </summary>
        public static void RoutinWork(bool isFolidayFlg)
        {
            if (isFolidayFlg)
            {
                new HolidayRoutin().Start(isFolidayFlg);
            }
            else
            {
                new WeekdaysRoutin().Start(isFolidayFlg);
            }
        }

        /// <summary>
        /// ルーティーンスタート
        /// </summary>
        public void Start(bool isFolidayFlg)
        {
            // 起床
            GetUp();

            // 準備
            Preparation();

            if (isFolidayFlg)
            {
                // まったり
                Relax();
            }
            else
            {
                // 出勤
                Commuting();
            }
        }

        // 起床
        protected abstract void GetUp();

        // 準備
        protected abstract void Preparation();

        // 出勤
        protected virtual void Commuting()
        {
            Console.WriteLine("出勤します。");
        }

        // まったり
        protected virtual void Relax()
        {
            Console.WriteLine("まったりします。");
        }
    }

継承先のクラス

休日クラスと平日クラスにさきほど作成した基底クラスを継承してみましょう。
さきほど抽象化した起床、準備メソッドを実装していきます。
ここでオブジェクト指向ポリモーフィズムがでてきます。

ポリモーフィズムとは・・・プログラミング言語の各要素(定数、変数、式、オブジェクト、関数、メソッドなど)についてそれらが複数の型に属することを許すという性質を指す。
アドホック多相(Ad hoc polymorphism):ある関数が、異なる型の引数に対してそれぞれ異なる実装を持つ場合。多くのプログラミング言語で関数の多重定義としてサポートされる。
パラメータ多相(Parametric polymorphism):コードが特定の型を指定せずに書かれることで、さまざまな型に対して透過的に使用できる場合。オブジェクト指向言語ではジェネリクスジェネリックプログラミングとしても知られる。関数型言語の分野ではパラメータ多相のことを指して単に多相性と呼ぶ場合がある。
部分型付け(Subtyping):部分型多相(subtype polymorphism)や包含多相(inclusion polymorphism)とも。共通の上位型をもつ複数の型を、1つの名前で扱う場合。オブジェクト指向言語の分野では部分型付けのことを指して単にポリモーフィズムと呼ぶ場合がある。

ポリモーフィズム - Wikipedia
Wiki調べ。

奥が深すぎてよくわかりませんが、オブジェクトのメソッドに多様なふるまいを持たせることなので、 overrideで処理の上書きをしていきます。

休日のルーティンクラス

    /// <summary>
    /// 休日のルーティン
    /// </summary>
    public class HolidayRoutin : RoutinWorkBase
    {
        protected override void GetUp()
        {
            Console.WriteLine("7:00に起きる。");
        }

        protected override void Preparation()
        {
            Console.WriteLine("7:10分から準備します。");
        }
    }

平日のルーティンクラス

    /// <summary>
    /// 平日のルーティン
    /// </summary>
    public class WeekdaysRoutin : RoutinWorkBase
    {
        protected override void GetUp()
        {
            Console.WriteLine("7:30に起きる。");
        }

        protected override void Preparation()
        {
            Console.WriteLine("7:40分から準備します。");
        }
    }

実行

     RoutinWorkBase.RoutinWork(true);
     RoutinWorkBase.RoutinWork(false);

結果

     7:00に起きる。
     7:10分から準備します。
     まったりします。
     7:30に起きる。
     7:40分から準備します。
     出勤します。

出勤を休日にする場合。

もし出勤が無くなって休日になった場合はCommuting(出勤)メソッドでをRelax()を呼ぶようにすればコードの修正がここだけで終わります。
virtualの場合は柔軟に対応できるので便利ですね。
ちょっと強引な気もするのでもっと良い方法ないか、デザインパターンの勉強もしていきたいと思います。

        protected override void Commuting()
        {
            base.Relax();
        }

結果

     7:00に起きる。
     7:10分から準備します。
     まったりします。
     7:30に起きる。
     まったりします。
     出勤します。

アプリ開発サークル勉強会⑨ 開催日時 2021年2月27日(土) 7:00-9:00

本日もこちらの問題やりました!

Q36-40 https://gist.github.com/kenmori/1961ce0140dc3307a0e641c8dde6701d

for文

for in

developer.mozilla.org

注: for...in はインデックスの順序が重要となる 配列 の繰り返しには使うべきではありません。

順序の保証がないそうです。
index番号を列挙したkey値が借り変数keyに入る。

var numbers = [1, 2, 3, 4, 5];

for (key in numbers) {
    console.log(key);
}

結果: 0,1,2,3,4

hogeが表示される例

var data = ['apple', 'orange', 'banana'];

Array.prototype.hoge = function () { }

for (var key in data) {
    console.log(key);
}

結果:

0,1,2,hoge

for of

順序の保証の保証がされる反復処理をしたい場合は for ofを使う。
dataに列挙されたvalueが仮変数に入る。
hogeが表示されない。

var data = ['apple', 'orange', 'banana'];

Array.prototype.hoge = function () { }

for (var value of data) {
    console.log(value);
}

結果:

apple,orange,banana

AWS ELB ALB作成

ELBを作成してnginxの負荷分散を確認したい。

ELBとは

アプリケーションのトラフィックを複数のターゲット分けることで負荷分散を可能にする。
4種類のElastic Load Balancerが存在し、耐障害性を高めるのに必要な高い可用性、自動スケーリング、堅牢なセキュリティが特徴。

Elastic Load Balancing(複数のターゲットにわたる着信トラフィックの分配)| AWS

アプリケーションが落ちた際に、別のインスタンスに紐づけしておけば、
完全にサービスが止まることはないので
故障に備えた設計(Design for Failure)を行うことができますね。


ELBを作っていきます。
VPC Subnet RouteTable InternetGateWay SecurityGroup EC2Instance
このへんはあらかじめ作っておきましょう。

ELB

マネージメントコンソールからEC2に入ります。
その後、ロードバランサーの作成。
f:id:Tokuty:20210223231237p:plain
種類は3 + 1ありますが、
ELBの動きをnginxを使ってhttp通信で確認したいのでApplication Load Balancerを選択。
f:id:Tokuty:20210223143931p:plain

ロードバランサーの設定

リスナーはデフォルトでhttpのポート80が設定されているのでそのまま。
アベイラビリティーゾーンにVPCと負荷分散させたいEC2を設置してあるSubnetを設定します。
注意点はアベイラビリティーゾーンが同じではないのとIGWが設定してあること。
f:id:Tokuty:20210223144103p:plain

セキュリティーグループ

EC2にログインする時のsshとhttpがインバウンドルールに設定してあるセキュリティーグループを選択。

ルーティンググループ

ここでルーティングを設定していきます。 ヘルスチェックのパスに負荷分散したいルートを設定します。
特に要件がないのですべてデフォルトで設定。
f:id:Tokuty:20210223152502p:plain 負荷分散させたいEC2インスタンスを登録。
f:id:Tokuty:20210223145312p:plain
説明の状態がProvisioningからactiveになれば準備完了。
EC2インスタンスアプリケーションサーバーが起動状態で、DNSからアクセスすると負荷分散の確認ができます。
次はnginxの設定をしていきます。

Nginx設定

EC2にssh接続にてログインした後に、Extras Libraryからnginxをinstallしていきます。
aws.amazon.com

amazon-linux-extras installできるpackageの確認
amazon-linux-extras install nginx1 install
デフォルト設定だと/usr/share/nginx/html/直下のindex.htmlが
最初に表示されるページとなります。
index.htmlの中身をELBにて切り替わるのを確認したいので適当に変更しておきます。 /usr/share/nginx/html/index.html 場所
systemctl start nginxnginxを起動

ELBのDNS名をURLに入力して確認します。
f:id:Tokuty:20210223150148p:plain
更新ボタンを押すことで切り替わることが確認できました。
f:id:Tokuty:20210223150158p:plain
試しにインスタンスを一つ起動停止にしてみると、このような結果となります。
ステータスがhealthyからunusedに変化したことが確認できます。
正常?がいいえとなります。
この状態でELBのDNS名にアクセスすると起動しているEC2インスタンス
index.htmlが表示されることが確認できました。
f:id:Tokuty:20210223152650p:plain
監視もできるので原因調査もできますね。

エラー

もしこのようなエラーが出た場合は、ターゲットにEC2インスタンスが設定してあるかを調べましょう。
f:id:Tokuty:20210223143519p:plain
もし何も表示されない場合はセキュリティーグループを見直してみましょう。
httpとポート80が設定されてないことが多いです。

nginxについて

gakumon.tech

アプリ開発サークル勉強会⑧ 開催日時 2021年2月20日(土) 7:00-9:00

Javascript アロー関数について①

アロー関数と通常関数の違いについて調べていました。
調べる前は通常関数の書き方を簡易的にしただけのイメージが強かったのですが、
どうやら違うようで使えなくなる機能があったため、使いどころに注意が必要です。

arguments

コードを書いて比較していきます。 引数の合計値を求める関数を定義しました。

通常関数

function sum() {
    var total = 0;
    for (var i = 0; i < arguments.length; i++) {
        total += arguments[i];
    }
    return console.log(total);
}

sum(1, 2);

結果:

3

アロー関数

var sum = () => {
    var total = 0;
    for (var i = 0; i < arguments.length; i++) {
        total += arguments[i];
    }
    return console.log(total);
}

sum(1, 2);

[object Object]こちらに値を代入しようとしていますが、argumentsが定義されていないので
エラーとなりました。
結果:

0[object Object]function require(path) {
      return mod.require(path);

スコープについて

スコープとは、直訳すると範囲という意味で、プログラミングだと 定義した変数がどの範囲まで使うことができるかを指します。 調べた限り、4つのスコープが存在するようです。
グローバルスコープ、ローカルスコープこのへんはどの言語でも共通の認識かと思われます。
グローバルは全体、ローカルは関数の中で変数を宣言した場合その範囲でしか使えない。
レキシカルスコープとダイナミックスコープについて。
変数のスコープの決まり方ですが、レキシカルスコープは宣言した時点で決定する。
ダイナミックスコープは実行時に決定する。
アロー関数はレキシカルスコープのようです。

this

thisの取り扱いについて。
難しいのでコードを書いて検証してみました。

引数の値の合計値を返す関数

通常関数

定義した関数の一つ上の階層にあるオブジェクトを返す。

function sum1(a, b) {
    console.log(this);
    return a + b;
}

sum1(1, 2);

結果:

{Object [global] {
  global: [Circular],
  clearInterval: [Function: clearInterval],
  clearTimeout: [Function: clearTimeout],
  setInterval: [Function: setInterval],
  setTimeout: [Function: setTimeout] {
    [Symbol(nodejs.util.promisify.custom)]: [Function]
  },
  queueMicrotask: [Function: queueMicrotask],
  clearImmediate: [Function: clearImmediate],
  setImmediate: [Function: setImmediate] {
    [Symbol(nodejs.util.promisify.custom)]: [Function]
  }
}

アロー関数

thisは定義されていないため、空っぽを返す。

var sum2 = (a, b) => {
    console.log(this);
    return a + b
}

sum2(1, 2);

結果: {}

testにvalueとtest関数を定義

通常関数

定義した関数の一つ上の階層にあるオブジェクトを返す。
この場合だと変数test1です。

var test1 = {
    value: 1,
    test: function () {
        console.log(this);
    }
}

test1.test();

結果:

{ value: 1, test: [Function: test] }

アロー関数

thisは定義されていないため、空っぽを返す。

var test2 = {
    value: 1,
    test: () => {
        console.log(this);
    }
}

test2.test();

結果:

{}

thisの動きが全く違いますね。。。
他にもたくさん違いがあるので、覚えることが多そうです。

参考サイト

qiita.com wemo.tech

AWS CloudFormationメモ①

CloudFormationメモ①

RDS

公式のリファレンスから引用。
AWS::RDS::DBSubnetGroup - AWS CloudFormation

AWSTemplateFormatVersion: "2010-09-09"
Resources: 
  myDBSubnetGroup: 
    Properties: 
      DBSubnetGroupDescription: description
      SubnetIds: 
        - subnet-7b5b4112
        - subnet-7b5b4115
      Tags: 
        - 
          Key: String
          Value: String
    Type: "AWS::RDS::DBSubnetGroup"

SubnetIds:
RDSにアタッチするSubentは異なるリージョン間のSubnetでないとエラーとなるため注意。

AvailabilityZone

AvailabilityZoneを設定する項目にap-north-east1(東京)このようなハードコーディングしていましたが、
マネージメントコンソール右上のAZと連動しているため、右上のAvailabilityZoneを東京以外に選択をしていた場合はAZが見つからないためエラーとなります。
なのでパラメーターとして選べるように。

Parameters:
 AvailabilityZonePublicSubnet:
 Type: AWS::EC2::AvailabilityZone::Name

Resources:
  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId:
        Ref: VPC
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: !Ref AvailabilityZonePublicSubnet
      Tags:
        - Key: Name
          Value: PublicSubnet

NetworkACL

  PublicNetworkACLInboundRule01:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId:
        Ref: PublicNetworkACL
      Egress: false
      RuleNumber: 100
      Protocol: -1
      RuleAction: allow
      CidrBlock: 0.0.0.0/0

  PublicNetworkACLOutboundRule:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId:
        Ref: PublicNetworkACL
      Egress: true
      RuleNumber: 100
      Protocol: -1
      RuleAction: allow
      CidrBlock: 0.0.0.0/0

Egressfalse:インバウンド true:アウトバウンド
Protcol TCP:6 すべて:-1
全許可のルールを追加するために-1を設定。
NetworkACLはデフォルトで全拒否のルールがインバウンドとアウトバウンドに設定されています。

EndPoint

yum updateができなかったときに作成したエンドポイント。
Amazon Linux2のRepositoryにアクセスできるようポリシーを設定しています。

  # Create Endpoint
  S3Endpoint:
    Type: "AWS::EC2::VPCEndpoint"
    Properties:
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Sid: "AmazonLinux2AMIRepositoryAccess"
            Principal: "*"
            Action:
              - "s3:GetObject"
            Resource:
              - "arn:aws:s3:::amazonlinux.*.amazonaws.com/*"
      RouteTableIds:
        - !Ref PublicRouteTable
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3"
      VpcId: !Ref VPC

EC2

新規作成の場合、AMIが存在しないため、パラメーターで新しいAMIを発行するように。
KeyPairの設定。password、アクセスキー、などは必ずパラメーターとして設定できるようにする。

Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instances
    Type: "AWS::EC2::KeyPair::KeyName"
  AMIID:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
  
Resources:
  PublicEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      Tags:
        - Key: Name
          Value: PublicEC2Instance
      ImageId: !Ref AMIID
      KeyName: !Ref KeyName
      NetworkInterfaces:
        - AssociatePublicIpAddress: "true"
          DeviceIndex: "0"
          GroupSet:
            - !Ref PublicSecurityGroup
          SubnetId:
            Ref: PublicSubnet

- AssociatePublicIpAddress: "true" publicIPAddressを設定しています。
これを設定しないと接続できなくなります。