2017年3月26日日曜日

schoo カスタマイズから学ぶPHP実践

Schooさんの授業を拝見してました。
「カスタマイズから学ぶPHP実践」


メモ

Plugins
  • BuddyPress
  • All in One SEO Pack
  • WooCommerce

laravel Auth
web.php Auth::routes();
--
Ruote::resource(...)
editなどのCRUDのメソッドを生成する

dd()
laravelのヘルパー関数

except()
laravel のセッションのうち、指定したパラメータ以外を取り出す
公式ドキュ

2017年3月11日土曜日

JAWS DAYS 2017 セッション1 「AWSでアプリ開発するなら知っておくべきこと」

初めてのJAWS DAYS参加です。
1発目のセッションは事前申し込みした「管理者に送る処方箋」ではなく、
「AWSでアプリ開発するなら知っておくべきこと」に出ました。


スケーラビリティ
水平・垂直

アーキテクチャのベストプラクティス
Design for failure
Build Security in Every Layer
Leverage Many Storage Options
Implement Elasticity
Think Parallel
Loose Coupling
Don't Fear Constraints

Everything fails, all the time.
by Wanner Vegl???

Design for failure
WebサーバとDBを分ける。
EC2とRDS

次にフェールオーバーや冗長性を考える
冗長構成にするなど。

Build Security in Every Layer
全てのレイヤーでセキュリティを確保

Leverage Many Storage Options
4種類のストレージを使い分けろ
  • S3
  • Glacier
  • EFS
  • EBS
4種類のDBを使い分けろ
  • RDS
  • Redshift
  • DynamoDB
  • ElastiCache

Implement Elasticity
動的な構成を前提とすること

Think Parallel
並列アーキテクチャを試すこと

Loose Coupling
疎結合
コンポーネントの中身を参照しないようにする

コンポーネントを結合した処理の場合、
キューにすることで一から再処理する必要はなくなる。

Asynchronous Integration
本当に即座にレスポンスが必要かを考える。
非同期処理のメリット
・アプリケーションがブロックされない(ユーザ体感の向上) ・よりスケーラブルになる

Don't Fear Constraints
スケールアップの他に、負荷分散やキャッシュも検討できる

The Twelve-Factor App
Herokuのエンジニアが公開したWebアプリ開発の方法論

Codebase
アプリトコードベースは1:1にしろ

Dependencies
特定の環境に依存しないようにする。
アプリと必要なモジュールを同梱してリリースする。

Config
環境によって異なる設定はOSレベルの環境変数によって注入されるべき

Backing Services
?

Build, Release, Run
上記3つのステージを厳密に区分すべき
各リリースに一意のIDを振るべき

Process
プロセス間共有をなくすべき
永続化するデータは外部領域にだす(DBなど)
ファイルやメモリはあくまでキャッシュとして扱い、永続化には用いないこと

Port binding
???

Dev/prod parity
本番環境と開発環境は一致させるべき
CI/CDは環境が同じであることが前提

ステートレスにするためのセッション情報の扱い
セッション情報はec2インスタンスで持たずに、
DynamoDBに外だしなどをする

DevOps
背景は、不確実性とスピード性が加速していること
Culture + Practice + Tool

Build → Test → Release Feadback ← ???

AWSのDocker管理サービス
ECS

自動ロールバック
失敗時の最も早いリカバリ

2017年2月28日火曜日

サムライズさんのJetBrains製品のハンズオンセミナー

サムライズさんのJetBrains製品のハンズオンセミナー


メモ

postfix completion

.var + tab → 変数に入れる

a + b.return + tab

.sout + tab

number &t; 18.if + tab

Emmet
dive.class + tab
script:src + tab

空気読む
山本さんのネーミングがセンスある
Alt + Enter

一つ前のペインに戻る
Control + tab
ファイルだけでなく、ツールウィンドゥを含む

閲覧履歴を開く
Cmd + e

パラメータ一覧を出す
Cmd + p

Shift + Cmd + Enter
Complete Current Statement
今の行の最後を終わらす。
");など

定義箇所にジャンプ
Cmd + b

Shift + f6
rename

リファクタリング
control + t

プロジェクトペインを開く
Cmd + 1

cmd + ↑ 探したい改装で ↓
そこでcmd + nでファイル作成もできる

cmd + n 画面で検索できる。
さらにその次の階層でも検索できる

Option + ↑↓
選択範囲の拡大・縮小

Opt + Cmd + L
コードフォーマット
選択して、範囲を絞ることができる。

PHP / Pythonには標準的なフォーマットがある
らしい。
あとは、Editor.configをプロジェクトルートに置く方法がある

SQLだとわかんない場所
Opt + Enter
Inject Language ...


RenameでAlterが書けてしまうので、
Read-Onlyをつけて置く。

SSHトンネルも掘れるよ。

Cmk + k
コミット
鍵マークを外すことで、diffの場所での変更が有効になる

Edit Json fragment
いい感じにエスケープしてくれる。

RegExpのテスト
1パターンだけはリアルタイムで判定する

2017年2月25日土曜日

Yaml入門 / Dotinstallで学ぶ

Yamlファイルに最近触れるけど、よくわかっていないのでDotinstallさんの動画を閲覧しました。
メモを残しておく。


メモ

Yamlとは
データ書式

公式サイト
YAML Ain't Markup Language

データ型
  • Scalar
  • Sequence
  • Mapping Hash

コメント
#ハッシュ記号です

Null値
~ チルダ

日付
yyyy-mm-dd

真偽値
true / false

Sequence
- (ハイフンとスペース)に続けて書く(=ブロックスタイル)
or
[]にカンマ区切りで書く(=フロースタイル)

ブロックスタイルの字下げ
ハイフンの前にスペースをつける
インデント前の要素は空白にする
- gee@nifty.com
- 
  - hoge
  - fuga
- yooo

Mapping Hash
key: value方式で: (コロンとスペース)で区切り。
こちらもブロックスタイルとフロースタイルが使える

SequenceとMapping Hashは交互に入れ子にできる

区切り文字にタブは使えない
注意

改行の取り扱い
|改行
最終行の改行を保持する。

|+
最後行以降の改行を保持する

|-
最後以降の改行を保持しない。

|を>に変えると、途中行の改行はスペースとなる

&でアンカー
*で呼び出せる(エイリアス)。変数みたいなもの。
- &hoge hogehoge
- *hoge

==
hogehoge
hogehoge
Mapping Hashは<<: *hoge
で呼び出す

--- と ...
データの区切りを示す
開始が---
終わりが...
1つのデータで、...がなくても問題はない。

Spring Batch / 区切り文字の変更

https://spring.io/guides/gs/batch-processing/ Spring Batchの公式サンプル

やってみてつまづいた点2点
・application.propertiesにDB定義しとかないいけない
・デフォルトパッケージだと動かないので、適当なパッケージ入れる必要がある
※パッケージに入れないのはテストやサンプルぐらいだと思いますが。。。

また、読み込むファイルの区切り文字の変更は「DelimitedLineTokenizer」のコンストラクトの引数で、区切りたい文字を渡す。
\tで、タブ区切りにした例です。
    reader.setLineMapper(new DefaultLineMapper() {
        {
           this.setLineTokenizer(new DelimitedLineTokenizer("\t") {
             {
              setNames(new String[] {"firstName", "lastName"});        
             }
           });        
           setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {
             {
              setTargetType(Person.class);        
             }
           });      
        }
    });

2017年2月20日月曜日

Spring Boot / Redirect先にオブジェクトを渡す

Spring Bootをいじってました。


RedirectAttributes attributes
Spring BootのGetting StartedでRedirect先にオブジェクトが渡せなくて1時間くらいハマってました。
結論、「RedirectAttributes attributes」で回避
  @PostMapping("/")
  public String checkPersonInfo(
          @Valid
          @ModelAttribute("personForm")
          PersonForm personForm
          ,BindingResult bindingResult
          ,RedirectAttributes attributes) {

    if (bindingResult.hasErrors() ) {
      return "form";
    }
    attributes.addFlashAttribute("personForm", personForm);
    return "redirect:/results";
  }
こちらを参考にさせていただきました。
Qiita SpringMVCでリダイレクト先ページにパラメータを渡す方法

brに閉じスラッシュをどうしてもつけたくない
意外とかったるいThymeleafのtemplatemodeの制約
LegacyHTML5だと単独タグでも閉じスラッシュが必要になる。
そこでtemplatemodeをLegacyHTML5にしましたが、この時はnekoHTMLというライブラリをimportする必要があるみたいです。
Gradleなら
dependencies {
        ...
 compile('net.sourceforge.nekohtml:nekohtml')
}

spring.thymeleaf.cache=falseを指定したのに、更新されない!どういうこと!?
IntelliJ上でgradle::bootRunしていて、spring.thymeleaf.cache=falseを設定の上、
HTMLファイルを更新してもブラウザで変更が確認できず調べる羽目になった。

結果、ファイル更新した後にbuildしないと内容は変わりません。
IntelliJ依存も疑って、Terminalでgradle bootRunしてみましたが、
これもbuildし直さなきゃHTMLファイルの変更すら反映されませんでした。

javax.validation.constraints.*のvalidation message
@NotNull(message="hoge")
以上!!簡単かつ簡潔
Spring Bootいいね!!

エラーページ
デフォルトなら、templates配下にerror.htmlを作ればよし。
エラーコードによる分岐はまた今度やります。
こちらを参考にさせてもらいました:システム開発メモ Spring Boot + Thymeleafでエラー画面をカスタマイズする

2017年2月19日日曜日

Perlのシジルの覚え方

Perl入学式という勉強会に参加して、覚えやすいシジルの覚え方を教わった


$
ScalorのS

@
ArrayのA

%
/を挟んで対応している=>なんか連想配列っぽい

Android is Dead.: Javaでメモリリークする件

Android is Dead.: Javaでメモリリークする件: Java プログラムでメモリー・リークが発生するのでしょうか? その通りです。 http://www.ibm.com/developerworks/jp/java/library/j-leaks/ メモリはリークするか まとめ 相互参照は問題ない。...



Javaで相互参照でメモリリークするのかどうか、この記事が一番しっくりくる柔らかい説明でした。もう循環参照以外から参照されないその循環参照は、GCの対象になるんですね。リファレンスカウンタ方式と世代別管理。。。まだまだ知らないことばかりです。

Git / githubのusernameを変更したら


Githubのusername変えたら、リモートリポジトリの書き換えが必要だったので、その実施メモ



メモ

git remote -v
今設定しているurlを確認
origin https://github.com/user_name/repository_name


git remote set-url origin https://github.com/new_user_name/repository_name
URLの書き換え

git remote -v
書き換わったことを確認

2017年2月11日土曜日

JVM入門

Schooの授業メモ
Apache Tomcatチューニング入門


メモ

Java/Tomcatアプリのレスポンスのボトルネック
keep-aliveの見直し、DB設計、SQL見直し
インデックスの見直し、Tomcatのメモリ設定

TomcatもJavaプログラム
知らなかったです。
TomcatもJavaプログラムのため、
物理メモリ → JVM → Tomcat → Webアプリ
という関係性のイメージになる

JVMの仮想メモリ
スタック領域 + ヒープ領域

スタック領域
参照型変数のアドレス参照とプリミティブ型変数を格納する

ヒープ領域
オブジェクトのインスタンスを格納する
実行速度に特に影響が出やすいのが、このヒープ領域

さらにEden領域・Survivor領域・Tenured領域に区切られる。
Eden領域 + Survivor領域 = New領域
Tenured領域 = Old領域ともいう。

Survivor領域については、From空間とTo空間
(Survivor0 / Survivor1)にさらに別れる。

Garbage Collectionの動き
インスタンスを生成して最初に格納されるのが、ヒープ領域のうちのEden領域
Eden領域がいっぱいになると、Scavenge GC(Minor GC)が起動する。
参照されていないインスタンスは破棄し、残りは
Survivor領域のTo空間(Survivor1)に移動する

その後のScavenge GCにおいて、参照されているTo空間のインスタンスは、
From空間(Survivor0)に移動する

デフォルトでは、16回マイナーGCを実行されたインスタンスは、
Tenured領域に移動します。
new領域とOld領域が一杯になるとFull GC(Major GC)が実行され、
一時的にアプリが停止します。
以上のように、GCの対象になるかどうかは参照があるかどうかですが、
GCが実行されるタイミングは、メモリ容量によって決まります。

JVMのプロセスを表示
JVMのプロセスを表示
$ jps
3528 Jps
2554 
3403 Bootstrap
2188 

-vをつけると、実行コマンドを確認できる
$ jps -v
3529 Jps -Dapplication.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home 
-Xms8m
2554  -javaagent:../Eclipse/lombok.jar -Dosgi.requiredJavaVersion=1.8 -Xms40m 

JVMプロセスのメモリ使用状況
jstat -gcutil  3403
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00  68.59  90.99  38.86  96.71  92.41      9    0.121     1    0.059    0.180
FGCがFull GCが発生した回数
FGCが発生していた時間

単発は問題ない(メモリを解放するので悪いことではない)が、
頻発しているとアプリが止まっているので、問題がある
項目の詳細は公式から
  • S0 : Survivor0の使用率
  • S1 : Survivor1の使用率
  • E : Eden領域の使用率
  • O : Old領域の使用率
  • P : Permanent領域(Tenured領域の別名)の使用率
  • M : メタスペースの使用率
  • CCS : 圧縮したクラス領域の使用率
  • YGC : マイナーGCの回数
  • YGCT : マイナーGCの時間
マイナーGC = Young GCの理解ですが、時間があったら確認したい。

Stop The world
Full GCにより一時的にアプリが停止すること(スレッドの停止)

OutOfMemmoryError
Full GCでもメモリ不足が解消できない状態

指定メモリが大きすぎるのも問題
メモリ・CPU・アプリケーションの性能により、
単純にメモリを大きくすれば良いという話ではないらしい。
  • マイナーGCに時間がかかる:New領域が大きすぎる
  • フルGCに時間がかかる:Old領域が大きすぎる

JVMの起動時の設定
  • -Xms:ヒープ領域の起動時のサイズ
  • -Xmx:ヒープ領域の最大サイズ
  • -XX:NewSize:New領域のサイズ
  • -XX:MaxSize:New領域の最大サイズ
  • -XX:SurvivorRatio:From/To領域の使用比率
  • -XX:MaxTenuringThreshold:New領域からOld領域に移動する閾値
  • -XX:TargetSurvivorRatio:Survivor領域の閾値

起動オブションの設定
・引数で渡す
・設定ファイルに書いておく(setenv.sh/setenv.bat)

intelliJ IDEAの操作

Schooの授業とJetBrains公式
ショートカットはここも参照
Keyboard Shortcuts You Cannot Miss
Default Key Map
MAKING DEVELOPMENT AN ENJOYABLE EXPERIENCE あとは、公式販売代理店のサムライズさんの記事

開発効率あげるぞー


メモ

プロジェクト > モジュール
intelliJの階層構造は、「プロジェクト > モジュール」
Eclipseは「ワークスペース > プロジェクト」

クイックフィックス
Win:Alt + Enter Mac:opt + Enter

クラス作成の基本
psvm > public static void main(String[] args) { } sout > System.out.println;

補完
Win:(Ctrl + Space) or (Shift + Ctrl + Space)
Mac:Ctrl + Space
もう一度押すと、詳しくサーチしてくれるらしいです。

アドバイバーの表示
Win:alt + Enter
Mac:alt + Enter

インスタンスの生成(new Class())を書いて補完
introduce local variableが出てくるので、それを押下すると、
クラス名をキャメルケースにした変数を宣言してくれる。

Generate
Win:Ctrl + Enter
Mac:Ctrl + Enter

静的コード解析ツール
format string > +で文字列と変数をつなげているものprint(ln)している場合、
printfを提案してくれる。(alt + Enter)

その他、ラムダへの書き換えやStream APIなども対応

Postfix
list_variable.for まで書いてtabを押すと、拡張for文
list_variable.fori まで書いてtabを押すと、for文
instance.nn で書いてtabを押すと、!= nullのif文
instance.null で書いてtabを押すと、== nullのif文

たっけーけど、Ultimate版を購入してみた
新規IntelliJのみ1年ライセンスで16,000ぐらい

Rename
Refactorの基本 Win:Shift + F6
Mac:Shift + F6

Search everywhere
Win:Double Shift
Mac:Double Shift

Redo / Undo Win:Ctrl + z / Ctrl + Shift + z
Mac:Ctrl + z / Ctrl + Shift + z

たまにUndoをCtrl + yと間違えて、バッファー消しちゃうときがあります。

現在の行を削除
*更新* Win:Ctrl + y
Mac:Cmd + Del

WinとMacで違うみたいです。

現在の行を下にコピー
Win:Ctrl + d
Mac:Ctrl + d

カーソルも移動。公式はカーソルではなくcaretって言っている。

ファイルの場所の表示
Win:Alt + F1 → 「Project View」を選択
Mac:Alt + F1 + fn → 「Project View」を選択

実装や呼び出し元へジャンプ
Win:Ctrl押しながらクリック
Mac:Cmd押しながらクリック

これ慣れると便利です。

選択しているクラスなどの定義をポップアップ表示
Win:Ctrl + Shift + I
Mac:Cmd+Y

Editor以外のウィンドウからEditorに戻る
Win:Esc
Mac:Esc

アクティブなEditorのタブを閉じる
Win:Ctrl + F4
Mac:Ctrl + w
違うね。

アクティブなペイン(pane)を閉じる
Win:Shift + esc
Mac:Shift + esc

規定の番号に対応したpaneを開く(Project:1/Version Control:9)
Win:Alt + Num
Mac:Cmd + Num

ターミナルを開く
前項目のpaneに登録されていないようでして、 Win:未確認
Mac:opt + f12

ファイルの構成をポップアップ
Win:Ctrl + F12
Mac:Cmd + F12

OSのディレクトリアプリで表示
Win:未確認
Mac:Opt + Cmd + F12

Win:
Mac:

Win:
Mac:

Win:
Mac:

Win:
Mac:

Win:
Mac:

2017年2月8日水曜日

Spring Boot / Form周り

Spring BootのForm周りでつまずいたところのメモ
時々intelliJショートカットやGradleのメモ


メモ

Gradle / 拡張プロパティ
ext {
  springBootVersion = '4.0.0.BUILD-SNAPSHOT'
}

Gradle / buildscript
拡張プロパティやレポジトリ、ビルドツールの依存を記述
ライブラリの依存は別の場所
buildscript { 
 ext { // extended property
  springBootVersion = '2.0.0.BUILD-SNAPSHOT'
 }
 repositories {
  mavenCentral()
  maven { url "https://repo.spring.io/snapshot" }
  maven { url "https://repo.spring.io/milestone" }
 }
 dependencies {
  classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
 }
}

Gradle / タスク名は前方一致で特定できれば省略できる
公式参照

Gradle / -x
依存しているタスクを省略
$ gradle --daemon jar 
:compileJava
:processResources
:classes
:jar

BUILD SUCCESSFUL

Total time: 2.217 secs
--
$ gradle --daemon jar -x compileJava
:processResources UP-TO-DATE
:classes
:jar UP-TO-DATE

BUILD SUCCESSFUL

Total time: 0.844 secs


Spring / URLをパラメータとして受け取る
@RequestMapping("/{param}")
public String calc(@PathVariable int param) {

ちなみに、型が違うと下記のように怒られます
Tue Feb 07 22:24:50 JST 2017
There was an unexpected error (type=Bad Request, status=400).
Failed to convert value of type 'java.lang.String' to required type 'int'; nested exception is java.lang.NumberFormatException: For input string: "hoge"

少数は問題なかったです。

intelliJ + lombok
Qiita IntelliJ IDEA+GradleでLombokを使う
Enable annotation processing にチェックが覚えられない
Welcome画面で設定すればデフォルト設定できます。
現在Gradleの設定は、 compileOnly "org.projectlombok:lombok:1.16.12" でした

また、ディレクトリのインポート時にbuild.gradleにlombokをdependenciesに記載していなかった場合、
build.gradleに追記後、それをsynchronizedする必要があるみたいでした。
少なくても自分の環境では、synchronizedしないとimport lombok.*;は認識しませんでした。
  • @Data:getter/setter/toString/equals/hashCode
  • @AllArgsConstructor
  • @NoArgsConstructor
うむ、楽だ。

Spring / org.springframework:springloaded
htmlファイルの更新時に、再読み込みをするライブラリ
参照: Qiita Spring Boot + Thymeleaf + Tomcat + Gradleで業務系アプリ 躓いた所6点
buildscript {
 ext {
  springBootVersion = '1.5.1.RELEASE'
 }
 repositories {
  mavenCentral()
 }
 dependencies {
  classpath
                  ("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
  classpath "org.springframework:springloaded"
 }
}
開発効率上げるために入れたほうがいい。

Thymeleaf自体はgradleで
compile "org.springframework.boot:spring-boot-starter-thymeleaf"

またまた、thymeleafのキャッシュは開発時には切っておきます。
[application.properties]
spring.thymeleaf.cache=false

Spring / @Controllerと@RestController
かなり恥ずかしい話ですが、違いがよくわかっていなかった。
@Controllerが付いているクラスのメソッドの戻り値は、HTMLテンプレートのファイル名
@RestControllerがついているクラスのメソッドの戻り値はHTTPレスポンスボディ

参考:Qiita Spring MVCのコントローラでの戻り値いろいろ

Git / **/で再帰的にignore
参考:MindTo01s git-ignoreの設定

Spring / 2.0.0-SNAPSHOTで超絶シンプル@Controllerサンプルを試してみるも。。。
ルーティング(@RequestMapping)がうまくいかず、ファイルがあるのに404が出た
hotload=ONやhtmlcache=OFFの設定があったので、とりあえずミートしてみましたが、変わらず。
1.5.1.RELEASEで同じコードを試したら、問題なくルーティングできた。
無駄に時間食ったわ。。。

Spring / ModelとModelAndView
Modelはセッションの属性値を持つだけ。
ビューのファイル名は別途メッソドの文字列返り値として渡す。

一方、ModelAndViewはセッションの属性値に加え、viewNameとしてビューのファイル名をもつ。
// Model
@RequestMapping("/{num}")
public String index(@PathVariable int num, Model model) {
  model.addAttribute("msg", "arg: " +num);
return "index"; // index.htmlを開く

// ModelAndView
public ModelAndView index(@PathVariable int num, ModelAndView modelAndView) {
  modelAndView.addObject("msg", "total: " + res);
  modelAndView.setViewName("index");
return modelAndView; // index.htmlを開く

IntelliJ w/Mac 1行消す
Command + delete
Qiita 忙しい人のためのIntelliJ IDEAショートカット集(´-`)

Command + dかと思ったんですが、逆に1行増えました。。。。Duplicateっすね。

Spring / フォームの値受け取り
@RequestParam("form_name") Type var_name
public ModelAndView submit(@RequestParam("name") String name , ModelAndView modelAndView) {

forwardとredirect
forwardはURLは元のまま、
redirectはURLも遷移後のものとなります。
Modelの場合
return "forward:/";

ModelAndViewの場合
return modelAndView;

2017年2月7日火曜日

Spring Boot / JPAとか

Spring BootのJPA周りとかでつまずいたところのメモ


メモ

JPA /JPQLのつまずきポイント
@QueryのFrom句は、ドメインクラスの@Table(name=xxx)の指定とは関係がなく、
ドメインクラス名を指定する

****
具体的には、
ドメインクラスでこう指定し、
@Table(name = "customers")

リポジトリのJPAインターフェースを下記のように設定
public interface CustomerRepository
 extends JpaRepository {
    @Query("SELECT x FROM Customer x ORDER BY x.firstName, x.lastName")
    List findAllOrderByName();

}
customersだとmappingできないと怒られる。
ドキュメントをちゃんと読もう

RequestMappingの設定確認
@RestControllerをつけたクラスに、
対応した@RequestMappingが付与する

起動時の確認としては、ログにMapped "xxx" onto ....と出力されるかを確認する
Looking for @ControllerAdvice: 
 org.springframework.boot.context.embedded.
 AnnotationConfigEmbeddedWebApplicationContext@243c4f91
Mapped "{[/api/customers],methods=[GET]}" 
 onto java.util.List 
 com.example.api.CustomerRestController.getCustomers()
...

SQL / Primary key制約の解除
> ALTER TABLE table_name DROP CONSTRAINT primary_key_name ;

JPA / Pagingとsort
Mapping(Controller)
    @GetMapping
    Page<Customer&t; getCustomers(@PageableDefault Pageable pageable) {
        Page customers = customerService.findAll(pageable);
        return customers;
    }
Service
    public Page<Customer> findAll(Pageable pageable) {
        return customerRepository.findAll(pageable);
    }
Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer&t; {
    @Query("SELECT x FROM Customer x ORDER BY x.firstName, x.lastName")
    Page<Customer&t; findAllOrderByName(Pageable pagealbe);
}
URLパラメータで表示数を変化できる
http://localhost:8080/project?page=1&size=3
これ面白い。ちょうど検索数が多い場合の画面を実装どうしようと考えていたとこ。
Pageの内容だとこんな感じのJSON
{"content":[{"id":1,"firstName":"Hanamichi","lastName":"Sakuragi"},
{"id":2,"firstName":"Kaede","lastName":"Rukawa"},
{"id":3,"firstName":"Sho","lastName":"Sato"}],
"last":false,
"totalElements":5,
"totalPages":2,
"size":3,
"number":0,
"numberOfElements":3,
"first":true,"
sort":null}


Spring / 開発時にHTMLのキャッシュを無効化する
デフォルトはパフォーマンス向上のため、HTMLはキャッシュされる設定です。
そのため、HTMLキャッシュを開発時に無効化すると効率的にHTMLファイルの変更を確認できます。

方法は2通り
  1. application.propertiesで設定する
  2. Spring Dev Toolsを使用する
Spring Dev Tools はgradleならbuild.gradleのdependencyに加えておくだけ。

2017年2月5日日曜日

Eclipse

Eclipseのschoo授業を見てみた


ショートカット

Undo / Redo
  • Win:Ctrl + z / Ctrl + y
  • Mac:Ctrl + z / Ctrl + Shift + z

カーソルがある行を削除
  • Win:Ctrl + d
  • Mac:Ctrl + d

先頭末尾移動
  • Win:Ctrl + ↑→↓←
  • Mac:Cmd + ↑→↓←

カーソルがある行の移動
  • Win:alt + ↑↓
  • Mac:opt + ↑↓

カーソルがある行を前後行にコピー
  • Win:Alt + Ctrl + ↑↓
  • Mac:opt + Cmd + ↑↓

改行せずに行挿入
  • Win:Shift + Enter
  • Mac:Shift + Enter

不要なimport文の削除
  • Win:Ctrl + Shift + o
  • Mac:Shift + Cmd + o

対応する中かっこへ移動
  • Win:Ctrl + Shift + p
  • Mac:Cmd + Shift + p

フォーマット
  • Win:Ctrl + Shift + f
  • Mac:Ctrl + Shift + f

mainメソッドの実行
  • Win:Ctrl + alt + xj
  • Mac:Cmd + opt + xj

入力補完の呼び出し
  • Win:Ctrl + space
  • Mac:Ctrl + space

Rename
  • Win:Ctrl + Alt + r
  • Mac:Cmd + opt + r

プロジェクトサーチ
  • Win:Ctrl + h
  • Mac:Ctrl + h

2017年2月4日土曜日

あまり進展しないPostgre SQLメモ -case式

達人に学ぶ SQL徹底指南書を読んで、Postgre SQL DBで試してみました。


メモ

とりあえずpostgresql serverの起動
$ postgres -D /usr/local/var/postgres

いるはずのユーザのログインで、DBがないって怒られる
(usr) $ psql -U usr -W
Password for user usr: 
FATAL:  database "usr" does not exist
psql: FATAL:  database "usr" does not exist
$ 
なにやら、psql実行時ユーザと同じロール名でアクセスする際は、
-UをつけていてもDB名として認識されるみたいでした。
DB名を記載すれば、期待通り、-Uはロール名として認識してくれました。
$ psql -U usr -W testdb

\l
DBの一覧表示

# create database professional_sql ;
databaseの作成

# \c proffesional_sql
DBへの接続

新規テーブルの作成
create table Greatests (
  key char(1) primary key
  , x integer not null
  , y integer not null
  , z integer not null
);

\dt
テーブルの一覧表示

\i file
SQLファイルからクエリの実行

UNION / UNION ALL
UNIONは重複を削除
UNION ALLは削除しない

\w ファイル名
バッファに残っている内容をファイルに保存

PostgresqlでGreatest/Least関数使えるんですね
Release 8.1で追加されたみたいでした。
Add GREATEST() and LEAST() variadic functions (Pavel Stehule)
8.1 release note

都道府県テーブルを作る
東京都の人口が1,300万なので、
2バイトのsmallintでは足りず、4バイトのintegerがちょうど良さげ

最初に該当したwhen句を返す
対象値は重複させないようにする
ELSE句を省略すると
ELSE NULLとなる

条件法
「PならばQ」の論理式
「P→Q」と書ける

論理積(logical product)
「PかつQ」の論理式 「P^Q」と書ける

\r
クエリのキャンセル

テーブルのリネーム
alter table cousemaster rename to coursemaster;

# \! pwd
psqlプロンプトでlinuxコマンドを実行

# \d TABLE_NAME
テーブル定義を確認する
参考:PostgreSQLのpsqlでテーブル定義を確認する方法

テーブルに付く制約とカラムに付く制約
表現が正しいか自信がないが、あるカラムに対する制約はカラムに適用され、
複数カラムにまたがる制約はテーブルに適用されているみたいでした。
alter文やテーブル定義を確認しただけの推測です。公式ドキュメント読まな。。。
# alter table studentclub add primary key (std_id, club_id);
# alter table studentclub alter column main_club_flg set not null;

アルファにしてオメガ
最初にして最後
コトバンクより

$createdb hoge / $dropdb hoge
localのpostgresに対してcreate database hoge(drop database hoge)を実行する

データベース名
先頭はアルファベット
63文字以内
ユーザ名と同じデータベース名を推奨

DBに接続するPostgreSQLユーザ
指定がなければ、OSのアカウントと同じ名前を使用
Postgresを起動するOSユーザは、PostgreSQLユーザとしても存在する

mydb=> / mydb=#
mydb=> 一般ユーザ
mydb=# スーパーユーザ

SELECT version();
バージョン情報を取得

識別子を二重引用符で囲むと大文字小文字を区別する
公式ドキュメントを読んでてびっくりした。
SQLはキーワードと識別子に対して大文字小文字を区別しません。 
ただし、(上では行っていませんが)識別子が二重引用符で括られていた場合は大文字小文字を区別します。
version 8.4.4だけど、多分、最新でもそうでしょう。

COPYコマンド
クライアントとサーバが別で(localhostでなくて)、サーバにファイルを置かない場合、\copyコマンド
サーバにファイルを置く場合(COPYコマンド)
参照:CSVファイルをデータベースにインポートする
# copy coursemaster from '/Users/usr/test.csv' USING DELIMITERS ',';
from句でファイルをフルパスで書く必要性がありました。

ビュー
他のビューに対して、ビューをつくってもOK
CREATE VIEW tempview AS
    SELECT city, location
        FROM weather, cities
        WHERE city = name;

ウィンドウ関数
チュートリアルで説明されるほど、メジャーな関数なのですが、
自分がOracle DB Bronze SQLを勉強したときは、試験範囲ではなかったと思います。
利点は、集約しなくても、平均や順位を出すことができるということです。
avg(salary) OVER (PARTITION BY depname)
rank() OVER (PARTITION BY depname ORDER BY salary DESC)
OVER句をつけることにより、avg集約関数ではなく、ウィンドウ関数として扱われます。

また、partition by COLUMN_NAMEは省略可能で、この場合は全ての行を含む仮想テーブルを対象とします。
SELECT score, sum(score) over () from score_table;
また、ORDER BY句のみの場合は、
ウィンドウ範囲が広がっていくような動きになります。
SELECT score, sum(score) over (ORDER BY score) from score_table;
公式にもありますが、重複するscoreがsumに含まれないことに注意が必要です。 ウィンドウ関数は、SELECT句とORDER BY句でしか使えません


テーブルの継承
初めて知った。テーブルを拡張する場合に、選択可能な手段です。
デメリットはUNIQUE制約または外部キーと合わせて使えないこと。これは痛い
CREATE TABLE users (
  name text,
  create_dt date
);

CREATE TABLE super_users (
  approver text
) INHERITS (users);

文字列定数内に'シングルクォートを入れる
''と続けて2つシングルクォートを入力する

改行で文字定数を区切った場合
SELECT 'foo'
'bar';
 ?column? 
----------
 foobar

SELECT 'foo''bar';
 ?column? 
----------
 foo'bar

# SELECT 'foo'      'bar';
ERROR:  syntax error at or near "'bar'" at character 19
STATEMENT:  SELECT 'foo'      'bar';
ERROR:  syntax error at or near "'bar'"
LINE 1: SELECT 'foo'      'bar';
                          ^

エスケープ文字列定数
E'hoge'というように、シングルクォートの前にEをつける
エスケープ文字列定数内だとシングルクォートを入力するのに、''以外に\'も使える

引用符を指定する
$$や$hoge$と文字列定数の区切り文字を指定することができる

Oracle DBでは別名にasをつけない
トリビア

dropテーブルの権限は付与できない
テーブルの所有者しか、テーブルの削除はできない。権限をGRANTできない。
レコードの削除(DELETE)権限は付与することができる

PostgreSQLはレコードをDELETEしても、物理削除しない
知らなかったよー。

以下引用:OSS DB/Silverの例題解説「運用管理 - 基本的な運用管理作業(自動バキュームの概念と動作)」
PostgreSQLは追記型のデータ構造を採っており、
データをDELETEしても、データに削除済フラグがつくだけで、
物理的にはデータが削除されません。

UPDATEも内部的にはDELETEとINSERTを実行するため、
古いデータが残り、そのまま放置すると物理的なデータ量が増えていきます。
この削除済みデータの領域を回収するのがバキューム(VACUUM)機能であり、
それを自動的に実行するのが自動バキュームです。

PITR
Point In Time Recovery
特定時点への復旧のこと

createuserの方式変更
PostgreSQL 9.1:対話式
PostgreSQL 9.2:デフォルトで権限を付与しない

付与していないユーザ権限の剥奪
エラーにもならず、コマンドは実行される

RoleとUserに違いがない
PostgreSQLだとそうらしい

2017年1月29日日曜日

Gradle / 事始め2

書き足りなかった部分をプラス
途中からSpringも混ざりますが、ご容赦願います。


メモ

$ gradlew xxx -Pargs="hoge"
-Pargs:引数の設定

jarだけ消す
$ gradle cleanJar
[root]/build/libsディレクトリ配下にあるjarを消去できます。
生成済みのclassファイルは残ったままです。

サーバポートを変更してwebアプリjarを実行する
$ java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8888
でいけるはずですが、、、
no main manifest attribute, in demo-0.0.1-SNAPSHOT.jar
となりました。デフォルトポートで実行するぶんにはマニフェストファイル不要なんですがね。。。
mavenで作った際は指定できましたが、gradleだと何か足りていないみたいでした。

spring boot devtoolsを使用する
compile('org.springframework.boot:spring-boot-starter-web',
'org.springframework.boot:spring-boot-devtools')

結果、立ち上げ時のmainプロセスが、restartedMainプロセスに変わります。
これでホットデプロイできるらしいですが、これは完全サポートが保証されているわけではないみたいです。

build.gradle
sourceCompatibility:受け付けるソースコードのバージョン
targetCompatibility:クラスファイルのバージョン

SpringBootTest
package com.example;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.boot.test.web.client.TestRestTemplate;
import static org.hamcrest.CoreMatchers.is;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DemoApplicationTests {

 @Autowired
 TestRestTemplate template;


 @Test
 public void contextLoads() {
  ResponseEntity res = template.getForEntity("/", String.class);
  assertThat(res.getStatusCode(), is(HttpStatus.OK));
  assertThat(res.getBody(), is("Hello world"));
 }

}

Assertはstaticでないといけないっていうのが気をつけどこ

Java / try with resources句
tryに()カッコをつけて、その中で閉じる必要があるインスタンスを生成する
finally句がなくてOK

IntelliJでlombokを入れる
Preferencies → Install JetBrains plugin...
→ lombokで検索 → Install
libraryに追加した後にビルドパスに追加するのをお忘れなく。。。
Eclipseでもそうですが、libraryにjarをコピーしただけでは使えません。

また、Annotation Processorsを有効にしないと@AllArgsConstructorなどが認識されない
参考:Lombokプラグインをインストールする
Preferencies → Build, Execution, Deployment
→ Compiler → Annotation Processors
Defaultを選んで、右のペインで「Enable annotation processing」にチェックを入れる

IntelliJにCoverageというプラグインが入っている
Run with Coverageで実行するとどれだけテストがカバーできているかが表示される

Spring / @SpringBootApplication
下記3つのアノテーションを1つにまとめた効果
  • @EnableAutoCOnfiguration
  • @Configulation
  • @ComponentScan

Spring / CommandLineRunnerインターフェース
DIが可能になる(プロパティに@Autowiredをつけて、インスタンスを自動生成できる)
また、mainメソッドに
SpringApplication.run(xxx.class, args);
とすることでアプリを立ち上げられる。
もちろん、自クラスにrunメソッドを記載すること。

Java可変長引数([type]... hoges)
そんなに使わないから、ググりました。
ひしだま's 技術メモページ
  • 配列としてメソッド内で使える
  • 引数のうち一つだけ
  • 最後の引数の時だけ使用可能
  • 可変長引数と同じ型でオーバーロードして、どちらにも適用されるような呼び出しは、可変長で「ない」メソッドに引数を渡す

Spring / @ComponentScanの対象になるアノテーション
  • @Component
  • @Controller
  • @Service
  • @Repository

lombok/ @AllArgsConstructor
プロパティ全てを引数に取るコンストラクタを自動生成するCC

Java / ConcurrentMapインターフェース
スレッドセーフなマップ
実装はConcurrentHashMapクラスか、ConcurrentSkipListMapクラス。

Postgre SQL / ユーザの一覧
$ select rolname from pg_roles;
or
=> \du
Describe Userかな。。。

psql / \c (database name)
pslqでのDB接続は\c (database name)

Spring / JDBCでの接続
必要なもの
  • DBコネクタライブラリ
  • spring-boot-starter-jdbc
実行の流れ
  • NamedParameterJdbcTemplateインスタンス
  • SQL文字列
  • MapSqlParameterSourceインスタンス(SqlParameterSourceインターフェース)
  • NamedParameterJdbcTemplateのqueryForObjectメソッド実行

H2DBでインメモリな設定
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.sql-script-encoding=UTF-8

H2DBで永続化する
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:file:./target/db/testdb
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.sql-script-encoding=UTF-8

SQL / テーブルがなかったら、、、
CREATE table if not EXISTS salse_table ( id int, date timestamp );

2017年1月28日土曜日

Gradle / 事始め

今更感がありますが、Gradleを初めてちゃんと触れたので、メモメモ


メモ

Mac OSXでのJAVA_HOME設定
$ export JAVA_HOME=`/usr/libexec/java_home`
バッククォートです。
注意点は、JDK変えた時に改めてexportしないといけないことですか。
$ /usr/libexec/java_home --help
Usage: java_home [options...]
Returns the path to a Java home directory from the current user's settings.
ログインユーザの環境でのjava_homeを返します。

gvmもといSDKMAN
Groovy/Grails関連のパッケージ管理ソフト
$ curl -s "https://get.sdkman.io" | bash
でインスト

$ gvm install gradle
gradleのインストール
Installing: gradle 3.3
Done installing!


Setting gradle 3.3 as default.
で終わり。

バージョンを指定したインスト
$ gvm list gradle
DL可能なバージョンを表示
$ gvm install gradle 3.2.1
など。

デフォルトバージョンの設定
$ gvm default gradle [version]

$ gradle --version
とりあえず、パス通っているかを確認

Groovy / 文字列
'シングルクォート:文字列(charじゃない)
"ダブルクォート:GString($で変数を入れることができる...「なんだと」)

Groovy / メソッド呼び出し時のカッコ
引数がないとき、メソッドの引数としてメソッドを使うとき、式の右辺でメソッドを使うときは、()が必須 その他のケースで、引数があるときはなくてもOK
1つのメソッド呼び出しする行の時だけですね。

Groovy / defによる変数の宣言
def age = 99
型を省略して変数を宣言できます。
Javaにおける、Object型の変数と同じ扱いになるそうです。

ダックタイピング
実際の値が、処理に適したものかどうかでメソッドやプロパティを捉える。

クロージャ
{}で定義する
def closure = { param -> println "$param" }
引数に対して->処理を行う
$itをつかって、引数を省略することも可能
呼び出しは、
closure.call()または、closure()
カッコの省略はメソッドと同様。

<<によってタスクに定義することも可能
task printParam << { println "$it" }

分けて書く場合、
def closure = { param-> println "$param" }
task printParam {}
printParam.leftShift(closure)

built-in task
あらかじめ利用できるgradleのタスク
$ gradle tasksで一覧表示が可能
$ gradle tasks
The Task.leftShift(Closure) method has been deprecated and is 
 ..scheduled to be removed in Gradle 5.0. Please use Task.doLast(Action) instead.
        at build_441sas0jfgrsmxsyzaz0sazay.run
        (/Users/Shogo/gitdir/gradle_git/build.gradle:1)
:tasks

------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------

Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]

Help tasks
----------
buildEnvironment
 - Displays all buildscript dependencies declared in root project 'gradle_git'.
components
 - Displays the components produced by root project 'gradle_git'. [incubating]
dependencies
 - Displays all dependencies declared in root project 'gradle_git'.
dependencyInsight
 - Displays the insight into a specific dependency in root project 'gradle_git'.
dependentComponents
 - Displays the dependent components of components in root project 'gradle_git'. [incubating]
help
 - Displays a help message.
model
 - Displays the configuration model of root project 'gradle_git'. [incubating]
projects
 - Displays the sub-projects of root project 'gradle_git'.
properties
 - Displays the properties of root project 'gradle_git'.
tasks
 - Displays the tasks runnable from root project 'gradle_git'.

To see all tasks and more detail, run gradle tasks --all

To see more detail about a task, run gradle help --task 

BUILD SUCCESSFUL

Total time: 0.957 secs


Build Setup tasks / Help tasksのグループが確認できる

とりあえずのテスト
$ vim build.gradle
task hello << {
  println 'Hello Gradle world!'
$ gradle hello
Starting a Gradle Daemon (subsequent builds will be faster)
The Task.leftShift(Closure) method has been deprecated and is scheduled to 
 ..be removed in Gradle 5.0. Please use Task.doLast(Action) instead.
        at build_441sas0jfgrsmxsyzaz0sazay.run
 ..(/Users/Shogo/gitdir/gradle_git/build.gradle:1)
:hello <-----タスク名
Hello Gradle world! <-----タスクの出力

BUILD SUCCESSFUL

Total time: 4.332 secs

$ gradle properties
ビルドスクリプトで定義されているプロパティの一覧を表示

gradleのデバッグ

-q:エラーログのみ出力する
-i:INFOレベル
-s:例外のスタックトレースを表示
-S:例外のフルスタックトレースを表示
-d:通常のスタックトレースを含むデバッグログを表示

$ gradle help --task
タスクを指定してヘルプを確認できる

ビルドスクリプトファイル名をデフォルト(build.gradle)以外のファイル名にする場合
$ gradle -b build_new.gradle hello
-bオプションでビルドファイルを指定する

initタスク
手順
  1. プロジェクトルートとなるディレクトリを作成する
  2. そのディレクトリに移動する
  3. $ gradle init --type java-library

タスクのライフサイクル
  • Internal:内部的にしか参照できない機能。ユーザが直接使うことはできない。
  • Incubating:実験的な公開
  • Public(default):公開中  どのライフサイクルステータスもつけられていないときはパブリック
  • Deprecated:廃止予定のタスク

JCenter
Mavenレポジトリ

dependency
gradle init --type java-libraryで作ったbuild.gradle
dependencies {
    // The production code uses Guava
    compile 'com.google.guava:guava:20.0'

    // Use JUnit test framework
    testCompile 'junit:junit:4.12'
}
compile:プロダクションコードのコンパイルと実行に必要なライブラリを記載 test:テストコードのコンパイルと実行に必要なライブラリを記載

Google Guava
Javaのコアライブラリ

タスクの一覧をGUIで確認する
$ gradle --gui

ビルドする
$ gradle build
Starting a Gradle Daemon (subsequent builds will be faster)
:compileJava
Download https://jcenter.bintray.com/com/google/guava/guava/20.0/guava-20.0.pom
Download https://jcenter.bintray.com/com/google/guava/guava-parent/20.0/guava-parent-20.0.pom
Download https://jcenter.bintray.com/com/google/guava/guava/20.0/guava-20.0.jar
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test <-- テストの実行
:check
:build

BUILD SUCCESSFUL

Total time: 17.849 secs
実行すると、プロジェクトルート配下にbuildディレクトリができます。
再度、$ gradle build 実行しても、変更がないタスクはスキップされます。

$ gradle clean
buildディレクトリが削除されます

テストの実行結果
build/reports/tests/test/index.html
にテスト結果が記載されます。

テストコードの実行
$ gradle test

$ gradle tomcatRunWar

Gradleでは型の宣言が必要
最低でもdefが必要(Object型)

システムプロパティの使用
System.properties['xxx']
$ gradle -Dxxx=hoge [task]

もしくは、gradle.propertiesに記述する
systemProp.message=hoge
この場合、自動でプロパティファイルを参照するので、
引数は不要
$ gradle [task]

taskの定義
タスクの設定
<<あり:実行処理
<<なし:設定処理

2017年1月24日火曜日

Java/ org.w3c.dom

Java SE 1.4からある古いパッケージですが、今日初めて知ったので、少しメモ


メモ

Documentインターフェース
スーパーインスタンス:Node
HTML/XMLファイル全体をさすインターフェース。
ドキュメントツリーのルートを格納する。

Elementインターフェース
HTML/XMLファイルの要素のインターフェース

2017年1月22日日曜日

Groovy / Differences with Java

Groovyの公式ドキュメントを読んでみます。
参考:Differences with Java

実行環境:Groovy Version: 2.4.8 JVM: 1.8.0_111 IDE:IntelliJ IDEA 2016.3.3


Default imports

次のパッケージはデフォルトでインポートされていますので、
下記のパッケージのクラスは明示的にimportしなくても使えます。

  • java.io.*
  • java.lang.*
  • java.math.BigDecimal
  • java.math.BigInteger
  • java.net.*
  • java.util.*
  • groovy.lang.*
  • groovy.util.*
printlnで標準出力できます〜。(System.outがいらない)


Intellij IDE CEでJunitしてみる

プロジェクトを右クリックする
Open Module Settings
Libraries
+ button
Junitで検索
とりあえず現在の最新のjunit:junit:4.12を検索
OK

あとは実行クラスでassertするだけ

import org.junit.Assert;
Assert.assert();


Intellij IDE CEでgroovyしてみる

Groovyプロジェクトは最初から選べましたが、
実行してみるとSDKがないと怒られました。

実行環境がMax OSXなので、brew install groovysdkです。
先にgroovyだけでインストールしていると競合します。
(エラーメッセージにある通り、brew unlink groovy競合を回避できます)

...

が、しかし、
brewでのインストール先が、「/usr/local/Cellar/groovysdk/2.4.7」で
Intellijで選べないとこにあるわけです。
しょうがないので、公式からzipをダウンロードし、解凍したディレクトリを選択します。
これでコンパイルできます。


Multi-method(Runtime Dispatch)

オーバーロードされたメソッドについての話。
Javaだとコンパイル時にどのメソッドを呼ぶかが決まります。
一方、実行時の引数の型により、呼び出すメソッドが決まります。

公式のサンプルをIntelliJで実行できる形式にしたものが下記です。
※JUnitをライブラリに登録してあるものとします。

import org.junit.Assert;

int test(String arg) {
    return 1;
}
int test(Object arg) {
    return 2;
}
Object o = "Object";
int returnInt = test(o);

//println result;
Assert.assertEquals((long)1, (long)returnInt);


IntelliJの実行ショートカット

Ctl + Shift + r
MacでIntelliJを使うのに慣れていないものでして。。。

Array initializers

配列の初期化は[]でよろしくどうぞ。
{}はクロージャ(無名メソッド)で予約されているので、配列の初期化には使えないそうです。

unexpected token: 1 @ line 4, column 17.
   int[] array = { 1, 2, 3};
                   ^
こんな感じで怒られます。

クラスのフィールドのアクセス修飾子を省力するとprivateとなりgetter/setterが作られます

class Student {
    String name
}

Student person = new Student()
person.setName("hoge")

println(person.getName())
Javaだとデフォルトのアクセスレベルはパッケージプライベートです。

また、groovyで@PackageScopeアノテーションをつけることで、
パブリックではなく、パッケージプライベートにすることができるようです。
自分の環境だと下記のエラーでアノテーションとして認識してくれなかったのですが。。。

6: unable to resolve class PackageScope ,  unable to find class for annotation
 @ line 6, column 1.
   @PackageScope class Student {
コマンドラインで実行してもダメ、コンパイルの設定も問題なさそうでしたが。。。
stackoverflowでも同じ事例はなさそうで、
「Eclipseでクリーン実行したらエラーが消えた」という事例はありましたがIntelliJでクリーン実行なさげ。


EclipseでGroovyしてみる

上記のunable to resolve class PackageScope問題で、原因切り分けとして、
Eclipseで同じコードを実行してみます。
参考:Qiita Gradle + Spock + Eclipse環境
まずプラグインが入っていなかったので、入れます。
使用バージョンは、STS 3.8.3.RELEASE(Eclipse Neon.2(4.6.2))です。
Help → Install New Software... →
http://dist.springsource.org/snapshot/GRECLIPSE/e4.6/ に対して、groovyで検索してプラグインを入れます。
これで新規作成ウィザードでGroovy関連を使用できます。
結果、変わらず「PackageScope is not an annotation」でエラーでした。とりあえず次。


GroovyはTry with Resourceをサポートしていません

公式でARM(Automatic Resource Management)という言葉が出てきましたが、StackOverflowを見た限り、
Try with ResourceのことをARMとも呼ぶみたいです。
GroovyはTry with Resourceはサポートしていませんが、クロージャで代用することが可能みたいです。
該当するeachLineメソッドがドキュメントに載っていないので、定かではないのですが。。。
IOGroovyMethodsのpublic static <T> T eachLine(InputStream stream, Closure<T> closure)
が一番近しいですが、、、どうだか。


Static inner classes

若干Javaと異なるらしい

Static inner classes

これは全然変わらない。

Anonymous Inner Classes

インナークラスのインスタンス生成は、
outer.new.Inner()はサポートされず、new Outer(inner)で書く


Lambdas

Java8のラムダそのままの書き方ができないが、クロージャで代用できる。


GStrings

ダブルクォートで囲った文字列は、GStringとして解釈される。
ダラーマークを含む文字列が,JavaとGroovyで若干異なる出力になる可能性がある。
ただ、Java APIに沿ってGStringとStringをオートキャストしてくれる。
しかし、Objectクラスの場合は、実際の値がチェックされる。


String and Character literals

Groovyだとシングルクォートは文字列として扱われる。
char型の変数にシングルクォートの値が割り振られた時は、自動でcharにキャストする。
値を直接参照する時は、キャストされないので、明示的にキャストする必要がある。

キャスト方法

  1. (char)'a'
  2. 'a' as char
(char)'a'
String str = 'x'
char x = (char) str
println((Object)x.getClass().getCanonicalName())
println(x)
-----------
java.lang.Character
x
'a' as char
String str = 'x'
char x = str as char
println((Object)x.getClass().getCanonicalName())
println(x)
-----------
java.lang.Character
x


Primitives and wrappers

Groovyは変数を全てオブジェクトとして扱う、とさらっと書かれています。
そのため、プリミティブ型変数をラッパークラスに自動変換します。
Javaはボクシング(ラッパークラスからプリミティブ型変数への変換)より変数拡張を優先します。
Groovyでは、プリミティブ型変数の引数をラッパークラスとしてまずは扱うので、
JavaとGroovyとでオーバーライドしたメソッドの呼び出し先が異なる場合があります。


Behaviour of ==

==:値のチェック
a.is(b):参照のチェック
nullは==でいいみたいです。


Extra keywords

Javaのキーワードに加えて、Groovyはas, def, in, traitもキーワードです。


Conversions

時間があるときに、確認します。


参照サイト

公式以外はこれかな、、、
http://www.tutorialspoint.com/groovy/

Servlet / JSP 再入門とAWSやLinuxの雑記3

続き


メモ

Spring Tool SuitsにDB Viewerを入れる
パースペティクブ開こうとしたら入っていなかったです。
Eclipse MarketplaceからDLできました。
参考:Small Java World Eclipseの「DBViewer」プラグインを利用して「Java DB」の環境を作成し、SQLを発行してみる

Mac OSXでPostgreSQL立ち上げるのにハマりググる。
クライアントはすぐ見つかるが、サーバ側がなかなか起動できなかった。
失敗した方法:
PostgreSQL 9.0.4文書 17.3. データベースサーバの起動
$ postgres -D /usr/local/pgsql/data >logfile 2>&1 &
Mac OSXでbrewでpostgresqlをインストすると/usr/local/pgsql/dataにconfファイルがないみたいでした。

解決した方法:
Qiita Homebrewを使ったPostgreSQLのインストール(Mac OS Lion)
postgres -D /usr/local/var/postgres

JDBCのダウンロード
まぁ公式から。
Java SDKのバージョンにより、使用するJDBC Driverのバージョンが異なります。
  • 1.6 → JDBC4
  • 1.7 → JDBC4.1
  • 1.6 → JDBC4.2

JDBC API
(Class)java.sql.Drivermanager
: static Connection : getConnection(String url)

(interface)java.sql.Connetion
: static PreparedStatement prepareStatement(String sql)
: void close()

(interface)java.sql.PreparedStatement
: void close()
: ResultSet executeQuery()
: int executeUpdate()
: boolean execute()
: void setString(int parameterIndex, String x)
: void setInt(int parameterIndex, int x)
: void setDouble(int parameterIndex, double x)
: void setDate(int parameterIndex, Date x)

executeQuery(), execute(), executeUpdate()
  • executeQuery() = SQLを実行してResultset型の戻り値を返す
  • execute() = SQLを実行し、完了したかどうかのboolean値を返す
  • executeUpdate() = SQLを実行し、影響があった行数を返す

INパラメータ
PreparedStatmentに埋め込む"?"のこと。
インデックスは1始まり。まぁSQL絡みだから間違えないかな。

ResultSet
(interface)java.sql.ResultSet
: void close()
: boolean next()
: String getString(String columnName)
: int getInt(String columnName)
: double getDouble(String columnName)
: java.sql.Date getDate(string columnName)

JDBCの書き方
Class.forName("org.postgresql.Driver");
Connection con = DriverManager.getConnection
("jdbc:postgresql://localhost:5432/test?user=test&password=test");

PostgreSQLのserialがずれる
独自idカラムをserialかつPrimary Keyにしていたら、Webアプリでレコード追加した際に
idカラムが重複してエラーを起こしていた。シーケンスが、すでにテーブルにある値とずれることがあるらしい。
参考:ぺけみさお PostgreSQLでINSERT時に自動採番の主キーが重複してエラーが出る場合の対処法

JSP / Javaコードに変換されたソースのありか
Eclipseで確認しているのは、
[project root] / work / org.apache.jsp / [jsp file name]_jsp.java

jspファイルへのリクエストへの度に_jspServiceメソッドを実行
javax.servlet.jsp.JspWriter型のout変数にjspファイルの内容を書き込む
結果として、整形されたHTMLコードがレスポンスで渡される。

JSP / ディレクティブ
  • page:ページ設定
  • taglib:タグライブラリ
  • include:外部ファイルの読み込み

JSP / pageディレクティブ
<%@ attribute1="value1" attribute2="value2" ... %>
import属性は複数使用可能で、その他は一度しか使用できない。
pageディレクティブの設定は、そのページのみで有効
  • language:javaを指定
  • contentType:MIMEタイプと文字エンコード("text/html; charset=UTF-8")
  • pageEncoding:JSPファイルをサーブレットクラスに変換するときの文字コード("UTF-8")
  • import:一度の指定でカンマ区切りで複数のクラスをインポート可能
    e.g. import="java.util.*, java.sql.*"
  • extends:JSPから変換する際のサーブレットクラスのスーパークラス
  • info:JSPページの情報。javax.servlet.ServletインターフェースのgetServletInfo()で取得することができる
  • session:セッション有効化フラグで、デフォルトはtrue(有効)です

スクリプティング要素
  • スクリプトレット:Javaプログラムブロック <% xxx; %>
  • 式:値を出力する式 <%= xxx %>
  • 宣言:変数宣言とメソッド定義のブロック <%! xxx %>
  • JSPコメント:HTMLコメントと違い、レスポンスで返されるHTMLには含まれない <%-- xxx --%>
式は文末に;がいらないけど、スクリプトレットと宣言は;が必要
式は変数やメソッドを1回呼び出すだけだからだろうか。

暗黙オブジェクト
オブジェクトを明示的に生成しなくても使用できるオブジェクト
  • out
  • request
  • response
  • session
  • application
  • config
  • pageContext
  • page
  • exception

JSP / 他のファイルの入れ込み
  • includeディレクティブ:<%@ include file="xxxx" %>
    include元と先どちらも合わせてコンパイルするので、元で先のJSPタグを使用できる
  • includeアクション:<jsp include page="xxxx" />
    include元を先にコンパイルし、その後にinclude先のファイルの呼び出す(実行する)

JSP / forwardアクションタグ
<jsp:forward page="xxx" />
前項includeディレクティブとアクションは、あくまで呼び出し元がHTTPレスポンスを返す。
一方、forwardアクションは、呼び出し先がHTTPレスポンスを返す。

2017年1月21日土曜日

Servlet / JSP 再入門とAWSやLinuxの雑記2

続き


メモ

Eclipseでブロックコメント追加のショートカットキー(Mac OSX)
Ctl + Cmd + /
解除ができないみたいですが。。。

Eclipseで現在の行のコピーのショートカットキー(Mac OSX)
Cmd + Alt + ↑ : 現在の行を1行下にコピーする(カーソルは移動しない)
Cmd + Alt + ↓ : 現在の行を1行下にコピーする(カーソルを移動する)

Servletのエンコーディング
javax.servlet.http.HttpServletRequest
: void setCharacterEncoding(String env)

javax.servlet.http.HttpServletResponse
: void setContentType(String type)

Javaのパッケージ名は小文字で、ドメインの逆、ハイフンは使えないのでアンスコ使う
広く → 狭く
参考:めちゃログ 「Java」パッケージ名の付け方! そして作成する方法
一方、プロジェクト名はどうすべきなのか。。。

http request headerのformdataのx, y
クリック位置だそうです。知らなかった。
参考:それマグで! <input type=image>で送信すると、X,Y座標が送信されるので、調べたら闇だった

Servlet / HTTPリクエストヘッダとレスポンスヘッダ
(interface)javax.servlet.http.HttpServletRequest
: String getHeader(string name)
: Enumeration getHeaderNames()

(interface)javax.servlet.http.HttpServletResponse
: void setHeader(string name, String value)
: void setStatus(int status_code)

Servletでリダイレクト
String referer = req.getHeader("Referer");  // リファラーの取得
if ( referer == null || referer.equals( URL_STRING) ) {
  resp.setStatus(303); // ステータスの設定
  resp.setHeader("Location",  url); // リダイレクト先
} 

Javaの正規表現
(class)java.util.regex.Pattern
: static Pattern compile(String regex)
: static Pattern compile(String regex, int flags)
: Matcher matcher(CharSequence input)
参考:JavaDrive 修飾子の種類と指定方法
DOTALLフラグを初めて知りました。デフォルトでは、.(ドット)は改行コードを含まないんですね。
(class)java.util.regex.Matcher
: boolean matches()
: boolean find()
: String group()

servletでファイルアップロード
Apache commonライブラリを使います
(Class)org.apache.commons.fileupload.disk.DiskFilteItemFactory
: void setSizeThreshold(int sizeThreshold) : void setRepository(File repository)

Servelet クッキーの利用
  1. クッキーオブジェクト作成
  2. クッキー発行
  3. クッキー取得
1.クッキーオブジェクト作成
(Class) javax.servlet.http.Cookie : Cookie(String name, String value)
: String getName()
: int getMaxAge()
: void setMaxAge(int expiry)
: String getValue()
: void setValue(string newValue)

2.クッキー発行
(interface)javax.servlet.http.HttpServletResponse
: void addCookie(Cookie cookie)

3.クッキー取得
(interface)javax.servlet.http.HttpServletRequest
: Cookie[] getCookie()

Servlet セッションオブジェクトによるセッショントラッキング
javax.servlet.http.HttpSession
: Object getAttribute(string name)
: void setAttribute(String name, Object value)
: invalidate()
: setMaxInactiveInterval(int interval) # デフォルトは30分

  1. セッションオブジェクト取得
  2. セッションオブジェクトから情報を取り出し記録
  3. セッションの破棄
1.セッションオブジェクト取得
(interface) javax.servlet.http.HttpServletRequest
: HttpSession getSession(boolean create)
: HttpSession getSession()

2.セッションオブジェクトから情報を取り出し記録
(interface) javax.servlet.http.HttpSession
: Object getAttribute(String name)
: void setAttribute(String name, Object value)

3.セッションの破棄
(interface) javax.servlet.http.HttpSession
: void invalidate()
: void setMaxInactiveInterval(int interval)

Servlet / JSP 再入門とAWSやLinuxの雑記

枯れた技術ですが必要があり復習。全然入門レベルから抜け出せてないですが。

前提:
デプロイ予定:amzn-ami-hvm-2016.09.1.20161221-x86_64-gp2(CentOS6ベース)
開発環境:
Mac OSX
Spring Tool Suite 3.8.3(Eclipse Neon.2(4.6.2)ベース)


メモ

AWSの初期設定
  • locale変更(/etc/sysconfig/i18n)
  • NICの設定(/etc/sysconfig/network)
  • 固定IPの場合(/etc/sysconfig/network)
  • 一般ユーザでsudoしたい場合
  • sshのパスワード認証を禁止する
参考:お便利サーバー.com サーバーを前提としたネットワーク設定

locale変更
$ vim /etc/sysconfig/i18n
LANG="ja_JP.utf8"
LC_CTYPE="ja_JP.utf8"
参考:
Qiita sshでログインした時、localeまわりでエラーが出た場合の対処法
CentOS(6.0)でロケール関係の設定

固定IPの場合
/etc/sysconfig/networkにホストのIPアドレスとサブネットマスクを記載する
IPADDR=xx.xx.xx.xx NETMASK=xx.xx.xx.xx

一般ユーザでsudoしたい場合
$ usermod -aG wheel <USER> ←G=補助グループの設定。a=追加(ないと置き換え)
# groups <USER> ← 確認
# visudo
# %wheel  ALL=(ALL)       ALL  ←コメント(#)を外す
参考:
Qiita Linuxでユーザーをグループに追加する Qiita Linuxコマンドでユーザーのグループ確認・変更。

sshのパスワード認証を禁止する
# vi /etc/ssh/sshd_config
PasswordAuthentication no
参考:sshでパスワード認証を禁止するには

/etc/sysconfig/network
centosのネットワーク設定ファイル
HOSTNAMEの変更時に設定を忘れないこと
参考:
CentOS6.0でホスト名を書き換える

ZeroConf
ITプロ Linuxキーワード Zeroconf
DNSやhostsファイルを使用せずに、ホスト名だけでホストを特定する仕組み。
ということで、通常サーバには不要
$ cat /etc/sysconfig/network
NOZEROCONF=yes

Java8の"JDK"を入れる
java-1.8.0-openjdk.x86_64はJREなんですね。ややこしい。
どこかのwebサイトに載っていたおかげで知りました。
まぁyum searchのパッケージの説明にも書いてはあるんですが。。。
java-1.8.0-openjdk.x86_64 : OpenJDK Runtime Environment
いち開発者としてはjavac入りのJDKを入れます。
$ yum update -y
$ yum install -y java-1.8.0-openjdk-devel.x86_64


システムJava(1.7)のままだったので、1.8にふりかえます。
$ alternatives --config java
2 プログラムがあり 'java' を提供します。

  選択       コマンド
-----------------------------------------------
*+ 1           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
   2           /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:2


# java -version
openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-b15)
OpenJDK 64-Bit Server VM (build 25.111-b15, mixed mode)
# javac -version
javac 1.8.0_111
参考:Task Notes CentOSのalternativesでJavaのバージョン管理

tomcatの対応Javaバージョン表
公式Apache Tomcat Versions
まだalpha版だけどtomcat9も出ている。これはJava8が必要。
tomcat7/8.0/8.5はJava7で対応(tomcat7はWebSocket以外はJava6で問題なし)

service登録周り
/etc/rc.d/init.dに起動・停止スクリプトを置かないとサービス登録できません。
置いたら、
$ sudo chkconfig --add <service name>
$ sudo chkconfig <service name> on

SELinuxの確認
$ getenforce Disabled

IntelliJ CE(Community Editin)は Java EE非対応
大人の事情で、Eclipseを使うことにします。

Spring Tool SuiteにTomcatプラグインを入れる
今回はMarketplaceから入れました。Tomcat Manager Plugin 9.1.2

Mac OSXでEclipseを使うときは、¥ではなく\
¥だとEclipseがエスケープだと認識してくれない。。。

<html lang="ja">
「ダブルクォートいるっけ?」ググった。
改めて思うと、文字列をダブルクォートくくらないのは、Linuxのシェルくらいかな。

HTMLのテンプレート(Eclipse on Max OSX)
Preference → Web → HTML files → Templates → new HTML File(5) → Edit

cyberduckでAWS接続
FTPでなくSFTPでした。「pemどこに設定すんだろ」と思わず調べる
こちらのQiita記事(【AWS】cyberduckからファイルのアップロード、ダウンロードができない)に感謝です。

jarのデプロイ
参考:
迷走男子!! [Tomcat] Tomcatへのwebアプリのデプロイ方法(jarファイル編)
(tomcat_base)/webapps # tree hoge
hoge
`-- WEB-INF
    |-- lib
    |   `--(deploy jar file)
    `-- web.xml
というふうに、webappsにディレクトリ分けた上で、下記を配備
  • libディレクトリ
  • deploy jar file
  • web.xml

2017年1月16日月曜日

Python / 最初の一歩1

Webスクレイピングしたい、ということでPythonやります


メモ

Mac
システムPythonを使うのもどうかなと思い、
pyenvでPython3系を使うことにした。

参考:Mac に Python 3.x 系と 2.x を共存するベストな方法
この記事3年前じゃん、、、どんだけ遅れてるんだ俺。
pyenv install 3.6.0 でこける
$ pyenv install 3.6.0
Downloading Python-3.6.0.tar.xz...
-> https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tar.xz
Installing Python-3.6.0...

BUILD FAILED (OS X 10.12.2 using python-build 20160602)

Inspect or clean up the working tree at /var/folders/hw/cjswx79j0zg_q040bz66_d8m0000gn/T/python-build.20170116211951.2465
Results logged to /var/folders/hw/cjswx79j0zg_q040bz66_d8m0000gn/T/python-build.20170116211951.2465.log

Last 10 log lines:
  File "/private/var/folders/hw/cjswx79j0zg_q040bz66_d8m0000gn/T/python-build.20170116211951.2465/Python-3.6.0/Lib/ensurepip/__main__.py", line 4, in 
    ensurepip._main()
  File "/private/var/folders/hw/cjswx79j0zg_q040bz66_d8m0000gn/T/python-build.20170116211951.2465/Python-3.6.0/Lib/ensurepip/__init__.py", line 189, in _main
    default_pip=args.default_pip,
  File "/private/var/folders/hw/cjswx79j0zg_q040bz66_d8m0000gn/T/python-build.20170116211951.2465/Python-3.6.0/Lib/ensurepip/__init__.py", line 102, in bootstrap
    _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
  File "/private/var/folders/hw/cjswx79j0zg_q040bz66_d8m0000gn/T/python-build.20170116211951.2465/Python-3.6.0/Lib/ensurepip/__init__.py", line 27, in _run_pip
    import pip
zipimport.ZipImportError: can't decompress data; zlib not available
make: *** [install] Error 1
「すぐにググるのは最低な奴がすることだ」と誰かに言われた気がする。
とはいえ、立ち向かえなさそうなエラーのため即ググる。
参考:Qiita MacでPython 3.5.0インストールに失敗したら
xcode-select --install
xcodeのCLIツールが必要らしい
その後は無事成功

pyenv install --list
pyenvでダウンロード可能なバージョン一覧

pyenv versions
インストール済みのバージョン一覧

GithubのSSH公開鍵が違っていたりとかね
cat ~/.ssh/id_xxx.pub
を貼り付け

$ pyenv local 3.6.0
実行ディレクトリでpythonバージョンの変更

$ pyenv global 3.6.0
システム全体で使用するpythonバージョンを変更する

pyenv local xxxしてもバージョンが変更されない
  • eval "$(pyenv init -)"が実行されていない
  • $ which pythonが「/usr/local/bin/pyenv」のようにpyenvを示していない
の2つの場合があるそうです。参考:Qiita pyenvでPythonがSystemバージョンから切り替わらない時の対処
vim /etc/pathsが探索パスだと初めて知った。謝謝。

今日は環境構築でおしまい

2017年1月15日日曜日

PHP / DateTime

PHPでの日付・時間の取り扱い方を振り返ります。


メモ

$time = new DateTime('now');
現在時刻でDateTimeクラスインスタンスを生成する

$time->format('Y-m-d H:i:s')
指定したフォーマットで日付を返します。
Y=4桁の西暦
y=2桁の西暦
m=2桁の月
M=英単語の略称 e.g. Jan,Feb
d=2桁の日
H=24時間表記の時間
h=12時間表記の時間
i=2桁の分
s=2桁の秒

2017年1月14日土曜日

Schoo / Webサーバー運用のためのLinux実践 3rd

Schooのメモ


メモ

RTO
Recovery Time Objective
障害から復旧までの目標時間
参照:RPOとRTOの考え方
ちなみに、RPOはRecovery Point Objectiveで、復旧させる時点のことらしいです。

Ansible
構成管理ツール

KNOPPIX
Optimal Diskからの起動を前提としたLinux distribution

OS不調時の対処
  • OSの再インストール
  • 代理boot
  • Snapshotからの復元
  • Orchestrationシステムからの復元

>grub でOS起動が止まった場合
/boot/grub2/grub.cfgが読み込めていない可能性がある

Virtual BoxでISOファイルから立ち上げる
マシンを停止させる
設定
ストレージ
IDE Controllerで光学式ディスクを追加
(今回はLive DVDにチェックを入れてみました)
システム
Boot OrderでOpticalを一番上にする
マシンを起動する
Troubleshooting
Rescue a CentOS system
1) Continue
$ chroot /mnt/sysimage
$ cd /boot/grub2
$ grub2-mkconfig -o /boot/grub2/grub.cfg $ exit $ exit

自動再起動
起動中のkernelパニックに有効な対処は再起動
自動再起動を設定することで、素早く対処することができる
$ cat /proc/sys/kernel/panic
0
kernel.panicオプションの値で、1以上だとシステムが停止したら自動で再起動する

- 設定 -
$ vi /usr/lib/sysctl.d/00-system.conf
~
kernel.panic = 10
$ sysctl -p 00-system.conf # 設定の反映
$ sysctl kernel.panic
kernel.panic=10 # 設定の確認

カーネルパニックを起こしてみる
echo c > /procy/sysrq-trigger
実際に10秒ぐらいで再起動かかった
ただ、ログイン必要ですね。。。。
現地には行かなくても済むけど、サービス断の短期化の効果は小さい

Schoo / Webサーバー運用のためのLinux実践 2nd

Schooのメモ


メモ

UEFI
Unified Extensible Firmware Interface
UEFIはBIOSに変わるブートローダ

grub2-mkconfigがない場合
yum install -y grub2でインストールしたgrub2-toolの中に入っているみたいでした。

起動ログの標準出力
$ cat /etc/default/grub
~
GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhbg quiet crashkernel=auto biosdevname=0 net.ifnames=0"
~
$ grub2-mkconfig -o /boot/grub2/grub.cfg # 修正を実体に反映させる

rootパスワード紛失時の変更
CentOS6まで:シングルユーザーモードでrootパスワードリセット
CentOS7:シングルユーザーモードへの移行にrootパスワードが必要に!
-> 初期ramディスク=initramfsマウント時点で処理を止める
(=rootfsロード前)

rd.breakオプションで処理を止める
起動ブートローダ選択時にeを押す
linux16で始まる行の最後に、「rd.break」と入力
ctrl xを押す
swithc_root:/# というプロンプトになります。
# mount -o remount,rw /sysroot #/sysrootを読み書き可能で再マウント
(読み取り専用になっているらしい)
# chroot /sysroot # rootディレクトリの変更
# LANG=C # asciiコードを文字コードとして使用 # passwd root # rootユーザのパスワード変更
# passwd root
Changing password for user root.
New password:
BAD PASSWORD: The password is shorter than 8 characters
Retype new password:
passwd: all authentication tokens update successfully.
exit -> exitで改めてブートする

SELinuxの停止
$ getenforce
enabled
$ vi /etc/selinux/config
SELINUX=disabled
$ getenforce
Disabled

Schoo / Webサーバー運用のためのLinux実践 1st

Schooのメモ


メモ

OS起動の流れ
  1. BIOS起動@Mother Board
    1. ハードウェア初期化
    2. ブーとデバイス検索
  2. ブートローダ読み込み@Storage
    1. kernel展開
    2. rootfs mount
    3. Systemdの起動

FHS
Filesystem Hierarchy Standard
/(ルート)を頂点とした、階層構造のファイルシステム基準のこと

BIOS
マザボのROMに格納されている
POST(Power On Self Test)を最初に実行し、HW不良の有無を確認する

ブートローダ
kernelを起動するプログラム
LILO/ GRUB / GRUB2などがある
CentOS6=GRUB
CentOS7=GRUB2

rootfs
/(ルート)ディレクトリを管理するファイルシステム
まぁ名前の通りですね

rootfsをmountする前に、
初期ramディスク(initramfs)からデバイスドライバをロードする

grub.cfgの編集
GRUB2のコンフィグファイルである/boot/grub2/grub.cfgは直接編集できない
編集用の/etc/default/grubを編集したのちに、grub2-mkconfigコマンドで反映させる

CentOS7のランレベル
数字ではなく、UNITの値で操作する

起動レベル対応表
  • CentOS6 : CentOS7
  • 0 : poweroff.target
  • 1 : rescue.target
  • 2-4 : multi-user.target
  • 5 : graphical.target
  • 6 : reboot.target
まぁ慣れれば、7の方が分かりやすそうですね。

起動レベルの変更(システム起動時)
起動中にe
linux16で始まる行で systemd.unit=rescue.xxx ctrl + x で起動

起動レベルの変更(システム起動中)
systemctl isolate xxx.target

DAS
Direct Attached Storage
1つのサーバがあるストレージを占有する方式
クライアントからDASへアクセスする場合は、
クライアント -> サーバ -> ストレージという流れになり、
アクセス速度は高速ではない。

Schoo / Webサーバー運用のためのLinux実践 - 5th/6th

Schooさんの授業のメモ


メモ

fdisk -l
接続されているディスクの一覧表示

IDEとSCSIでデバイスファイルが違うんですね
/dev/hda IDEタイプHDD
/dev/sda SCSIタイプHDD
参考:/dev/hdaとか/dev/sdaとはなんぞや?

パーティションの種類
  1. 基本パーティション
  2. 拡張パーティション
  3. 論理パーティション

基本パーティション
4個までしか作れない上、4個作ってしまうとそれ以上パーティショニングが実行できない。

拡張パーティション
論理パーティションを格納するためのパーティション
拡張パーティション自体はデータを保存できない

論理パーティション
拡張パーティション内に作成される、データ格納用のパーティション


fdisk /dev/sd?
追加したディスクに対してディスクのパーティションを作成する
n -> p -> Enter -> Enter -> +nG (サイズに該当) -> w(終了)

mkfs -t xfs /dev/sdn
centosは上
ubuntuはmkfs.xfsをインストする

blkid /dev/
デバイスのファイルシステムを確認できる

マウント
一時的なマウントと永続的なマウントがある

mount -t xfs -o defaults /dev/ /
一時的なマウント

/etc/fstab
$ cat fstab
LABEL=cloudimg-rootfs / ext4 defaults 0 0
/dev/sdb1 /mnt ext2 defaults 0 0

mount -a
fstabの内容に沿ってマウントしてくれる。
シャットダウンで永続的マウントを確認する前に、
こちらで確認する

そもそもVirtual Boxへの仮想HDDの追加方法
Virtual Box -> マシンを選択しSetting※停止中であること
-> Storage -> box-diskを含むControllerの右横のディスクの追加ボタン
-> 今回はvmdkを追加しました。
これで、/dev/sdbからsdc,sddへと追加されます。

fdisk /dev/sdn
コマンド (m でヘルプ):t
※ パーティションのシステム ID を変更する
8e Linux LVM

partprobe
inform the OS of partition table changes(man)
パーティションの内容を変更したら、念のためOSに変更を通知する

Physical Extent
物理ディスク(デバイス)を仮想的に分割する最小単位

Physical Volume
物理ディスク(デバイス)を PE単位で分割した仮想ボリューム
Physical Volume=物理ボリュームという割には仮想的なボリュームです。

pvcreate /dev/device_file1 /dev/device_file2
Physical Volumeの作成

pvdisplay /dev/device_file1 /dev/device_file2
Physical Volumeの詳細表示

vgcreate volutemGropu /dev/device_file1 /dev/device_file2
Volume Groupの作成

vgdisplay -v volutemGroup
Volume Groupの確認

lvcreate -L nM -n logicalVolume volumeGroup
Logical Volumeの作成

lvdisplay volumeGroup/logicalVolume
Logical Volumeの確認

LVのサイズを変更するには、
パーティションのサイズの変更
ファイルシステムのサイズを変更

lvextend -L 50M /dev/volumeGroup/logicalVolume
パーティションのサイズの変更

xfs_growfs /dev/volumeGroup/logicalVolume
ファイルシステムのサイズを変更

Schoo / Webサーバー運用のためのLinux実践 4th

Linuxはまだまだ入門者の域を抜けられないので、少しSchooで勉強


メモ

ファイルシステム
ディスクベースとメモリベースに分けられる
ディスクベース:xfs, ext n, btrfs メモリベース:tmpfs

ttyコマンド
接続している仮想端末のデバイスファイル名を出力する

dd if=/dev/zero of=/boot/grub2/sample bs=4000 count=10
/dev/zero=Linuxのスペシャルファイルの一つ。全てNULL文字

du
オプションなどがうろ覚え
du -h dir/file

df -i
inodeの使用状況の表示

ls
デフォルト=ファイル名の昇順
-U=ディレクトリ内の順番で出力
-S=サイズで降順
r, h, t, l, 1あたりは使うのでわかるんですけどね、ここら辺はU,Sはなかなか使わないですね。

echo
Schoo関係ないけど、仕事中に調べた事項
-eをつけないと¥nを改行コードとして扱わない!
-nをつけると、echoの最後の改行はなくなる

VFS
Virtual File System
Linuxのファイル管理システム
@ITさんの記事を後で読もう。

dd(1) で空ファイルを作るときは /dev/zero より seek
こちらの記事が勉強になりました。(dd(1) で空ファイルを作るときは /dev/zero より seek )

/dev/null
これもLinuxのスペシャルファイルの一つ。
明示的に消去する際に使いますね。

PHP / なかなか身につかないPHP

Code IQでHTMLのスクレイピングの問題が出ていたので、PHPで書いてみた。
課題はクリアできなく、振り返りです。

<?php
$input =  trim(fgets(STDIN) )  ;
$th = array();
$td = array();
while ( $input ) {
    // echo $input . "\n";
    preg_match('/^<th>(.*)<\/th>$/', $input, $match_th);
    preg_match('/^<td>(.*)<\/td>$/', $input, $match_td);
    // var_dump($match);
    if ($match_th ) $th[] =  preg_replace('/<\w*>/', '' , $match_th[1] );
    if ($match_td ) $td[] =  preg_replace('/<\/?\w*>/', '' , $match_td[1] );
    $input =  trim(fgets(STDIN) ) ;
}

printCsv($th);
printCsv($td);


function printCsv($array) {
    foreach ($array as $key => $var ) {
        echo "\"" . $var . "\"";
        if ( $key < count($array) -1 ) {
            echo ",";
        } else {
            echo "\n";
        }
    }
}



function e($target){
    return htmlspecialchars($target, ENT_QUOTES);
}
?>


メモ

trim(fgets(STDIN) )
標準入力の読み込みと両端スペースの消去

preg_match(regex_str or regex_array, str or array, $store);
パターンマッチした行とグループ化した部分を$storeに格納する

preg_replace(regex_str, inserted_str , target_str );
target_str内でregex_strに対応する部分をinserted_strに置き換える。
preg_matchと同様にregex_strとinserted_strは配列でも構わない

count($array)

PHPの配列の要素数のカウントを思い出せずググった次第です




foreach ($array as $key => $var ) {

同じく

htmlspecialchars($target, ENT_QUOTES);

同じく

fputcsv(output , array [, delimitter[, enclosure[, escape_char] ] ] )

配列をcsvで出力する
enclosureがつくルールがわからず、今回は使えず

2017年1月12日木曜日

[読後メモ]無線LANでスマホ・PC全部繋がる!Wi-Fi完全マニュアル

Wi-Fiの設定などについて理解を深める
さすがにWi-Fiに繋げることは理解していますが、
親機の設定などは把握仕切れていないので。。。

参考書籍:
無線LANでスマホ・PC全部繋がる!Wi-Fi完全マニュアル
井村克也 著


メモ

Wi-Fi ≠ 無線LAN
Wi-Fi = Wi-Fi Allianceがテストし正常性を確認したことを示すブランド名 無線LAN = 無線方式で構築するLAN

アドホックモード
無線LAN機能を持つ機器同士で直接通信すること
iPhoneのAirDropやBlue Toothでの通信もこれにあたりますね

アクセスポイントモード
ルーティング機能は持たず、スイッチとして中継する役割をする状態

AOSS
バッファローが提供している無線LANの簡易接続機能

WPS
Wi-Fi Protected Setup
無線LANの簡易接続機能
子機で待ち受け状態にした後、
親機でWPS用ボタンを押せば、パスワード不要でネットワークを認証することができる。
注意点は子機と親機は1m以内と、かなり近くで操作する必要がある。

また、ボタン方式だけでなく、PINコード方式もあり、
子機側で表示させたPINコードを管理画面に入力することで、子機をネットワークに認証させることも可能。

IEEE802.11ac
記事を書いている時点では、新しい部類の無線LAN規格
5GHz / OFDM(LTE) / Multi-User MIMO

WEP
Wired Equivalent Privacy
解読方法が知れ渡っているので、使わないこと。

WPA
Wi-Fi Protected Access
接続時にユーザー認証が必要なWPA-EAP(Enterprise Mode)
事前共有鍵で認証するWPA-PSK(Public Shared Key)

TKIP / AES
WPA-PSK, WPA-PSK2にはTKIP / AESの2通りの暗号化方式がサポートされている

コマンドプロンプト wlanコマンド
wlanコマンドを駆使する

2017年1月9日月曜日

Azure / ひと目でわかるAzure 基本から学ぶサーバー&ネットワーク構築<続き>

前回の続き

参考書籍:
ひと目でわかるAzure 基本から学ぶサーバー&ネットワーク構築
横山 哲也


メモ

ディスクストライピングの使用
手順
  1. ディスク追加
  2. 記憶域プールの作成
  3. ストライピングされた仮想ディスクの追加

記憶域ブール
こちらの記事を参考を拝見しました。
最低でもディスク容量が4GB必要
これではまってて、容量が少ないと、そもそも記憶域プールに使用可能なディスクグループがない。
Windows Server 2012で追加された機能
サーバマネージャ → ファイルサービスと記憶域サービス
→ ボリューム・記憶域プール
→ 右上の「タスク」プルダウンメニュー

仮想ディスクの作成
レイアウトの種類
  • Simple
  • Mirror
  • Parity

1アカウントで複数サブスクリプション
可能でした

請求額アラート(Preview)
機能の有効化
旧ポータル → 右上のプロフィール画像 → View My Bill
→ 上段のナビゲーションタブからpreview features → Billing Alert Service → Enable的な何か

Accountページ → Subscription → ALERTS
→ add alert
ちゃんとロケールに沿った通貨で設定できました。
参考:公式Doc

NTFS
Winで使われるファイルシステム
FAT系と違ってアカウントごとの権限制御がある、とのこと
参考:IT用語辞典

SMB(Server Message Block)
ファイル共有プロトコル

Azure旧ポータルの好きではない点
インスタンスのKPIグラフの縦軸が相対的であること

仮想ネットワーク
仮想マシン作成時にしか指定できない。
よって、インスタンス作成前に仮想ネットワークを作成しておくこと
仮想ネットワーク間のインスタンスの通信は、エンドポイントに設定していないポートも使用できる

RPIP
Reserved Private IP
  1. ローカルPCでPowerShellのAdd-AzureAccountをじっこする方法
  2. 新ポータルを使う方法

Windowsの仮想マシンバックアップ
ゲストベースバックアップ / ホストベースバックアップ

GPT
Guid Partition Table形式
ディスクのパーティション方式

MBR
Master Boot Record
ディスクの先頭セクターのこと、またはパーティション方式

ゲストベースバックアップ
手順の最後に再起動がかかります。
  1. ディスクをオンライン
  2. ディスクの初期化
  3. パーティションの作成
  4. フォーマット
ディスクの初期化によりPartitionがGPT形式になることを確認する
Dashboard → Add roles and features
Wizardに沿って、Roleのパートで、Windows Server Backupを選択する
閉じる

ローカルバックアップ
Windows Server Backupでスケジューリングするか、
即時バックアップするかをします。
スケジューリングでディスクを占有した場合、そのあとの即時バックアップでそのディスクは使用できない。
また、インスタンスを立ち上げた直後であってもSystem stateのバックアップは時間がかかる。
11GBで約1時間かかりました。

Azureバックアップ(オンラインバックアップ)

Recovery Serviceによる仮想マシンのバックアップ
本来はオンプレミス環境のバックアップをAzureに残す目的だそうですが、 公式ドキュメント参照

Express Route
Azureのデータセンターとオンプレミス環境を繋ぐためのVPN

AD DS
Active Directory Domain Service
ADを使ったドメイン管理
詳細は後でフォローします。

Azure / ひと目でわかるAzure 基本から学ぶサーバー&ネットワーク構築

Azureを触ってみようということで、書籍をなぞってみる。

参考書籍:
ひと目でわかるAzure 基本から学ぶサーバー&ネットワーク構築
横山 哲也


メモ

クラウドコンピューティング
煎じ詰めれば、サーバーの利用形態
一般的に認知されている定義はNIST(米国国立標準技術研究所)が公開した文書によるもの。
上記文章引用:
2. NIST によるクラウドコンピューティングの定義

クラウドコンピューティングは、共用の構成可能なコンピューティングリソース(ネットワーク、サー バー、ストレージ、アプリケーション、サービス)の集積に、どこからでも、簡便に、必要に応じて、ネ ットワーク経由でアクセスすることを可能とするモデルであり、最小限の利用手続きまたはサービス プロバイダとのやりとりで速やかに割当てられ提供されるものである。

サブスクリプション
Azureの課金の単位
コア数や共同管理者数、ストレージアカウント数などに制限がある
詳細は公式参照。
対応策としては、複数のサブスクリプションを運用するか、上限の引き上げを申請する。

管理ポータル
管理画面。AWSで言うところの、コンソール。

Region / Data Center
基本的なことですが、地域とデータセンターです。
GeoもRegionと同義

クラウドサービス
インターネットからのアクセスの単位
仮想マシンの「箱」に当たる
パプリックIPアドレスを1つ持ち、インターネットからアクセスできる。
クラウドサービス間のインスタンスのアクセスには、仮想ネットワークかインターネットを経由する必要がある。

仮想ネットワーク
仮想マシンを作る前に作成する必要がある。
注意点:
クラシックポータルで、仮想ネットワークがない状態で仮想マシンを作成した場合は、 クラウドサービス内のみで利用可能なネットワークが構成されます。

virtualの意味
面白いコラムだったのですが、virtualはどちらかと言うと「仮想」よりも「事実上の」と言う意味に近いそうです。
英語の「virtual」の第一義は「事実上の」で、例文として「virtual promise」が出ていました。これは「法的な形式は満たしていないけれども効力のある契約」の意味だそうです。
引用:横山 P20
へー、知らなかった。

クラウドサービスのURL命名規則
ドキュメントでは見つからなかったですが、わざとエラーメッセージを表示させてみた。
This field can contain only letters, numbers, and hyphens. The first and last character in the field must be a letter or number. Trademarks, reserved words, and offensive words are not allowed.
  • 文字
  • 数字
  • ハイフン※最初と最後には使えない
商標、予約語、不適切な表現は許可されない、とのこと。

Storageのレプリケーション
  • Locally Redundant(LRS):同地域の同施設に3つの複製を作成
  • Geo-Redundant(GRS):組み合わせが固定された別の地域に複製を作成:地域ごとに3つの複製を持ち、合計6つ
  • Read-access Geo-Redundant(RA-GRS):Geo-Redundantの複製先は直接利用できないが、こちらは読み取りが可能となる
  • Zone Redundant(ZRS):複数の地域・施設に複製を作成
Zone RedundantはブロックBLOBのみサポート
参照:公式

ストレージアカウントの主なサービス
  • BLOB(Binary Large OBject
  • Que
  • Table
  • File
また、BLOBは2種類ある。
  1. ブロックBLOB:連続再生に向いている
  2. ページBLOB:ランダムアクセスに最適化している
公式を読んでて面白いなと思ったのは、「LRSについては、データの書き込み時は3回レプリケートし、3つとも書き込まれた場合に、書き込みが正常に終了する」と言うこと。3つのレプリケーションのどれかが主であるわけではないんですね。
また、LRSはデータセンターレベルの障害でデータ損失の可能性がある(10年単位であるかないかだと思いますが)ので、MSとしてはGRSを推奨している。しかし、LRSが望ましいケースもあるとのこと。

GRSのリージョンペア
GRSのセカンドリージョンは固定
東日本と西日本がペアです。今のところ、もう少し離れててもいいじゃないかと。。。

仮想マシンが持つ動的IPアドレス(DIP)
DHCPサーバから割り当てられ、再起動するまでは同じ

Virtual Machineの種別
TierとSizeで分別される。 Tier = Basic / Standard
Basicの方は、機能が一部省かれます。
Azure ロード バランサーと自動スケーリング機能が提供されず、料金は最大で 27% 低く設定されています。
引用:Basic (基本) レベルの仮想マシン
Size = CPU, Memory, Disk, GPUの組み合わせ
Azureの仮想マシンのサイズを確認してみた
  • A-series
  • A-series - compute-intensive instances
  • Av2-series
  • D-series
  • Dv2-series
  • DS-series*
  • DSv2-series*
  • F-series
  • Fs-series*
  • G-series
  • GS-series*
  • H-series
  • N-series
A = 汎用、 D = SSD使用の入出力性能重視、 G = 大容量Memory使用の演算性能重視
F = Dv2シリーズと同じプロセッサを搭載しているものも、Dv2シリーズと比べ、コア当たりのメモリやローカルのSSD容量は小さい
Tier BASICで選べるのはA seiesのみ。

RDMA
Remote Direct Memory Access
ダイレクトメモリアクセス(Direct Memory Access (DMA))は、CPUが介在することなく、ホストメモリへ直接アクセスを行うデバイスの機能である。 RDMA (Remote DMA)は、CPUが関与することなくネットワーク越しにリモート計算機上のメモリへアクセスする(すなわち、リモート計算機上のメモリからリードおよびリモート計算機上のメモリへライトする)機能である。

参考:SSD情報

クラウドサービスのRDP時のポート
ランダムなポートが割り当てられる
通常はTCPの3389番

RTM
Release To Manufacutre
完成品

FCS
First Customer Shipment
最初の発送

SysPrep
サーバ固有の情報を抜いて仮想マシンイメージを作ることができるツール
GUIもあるが、/move:vmオプションが使えない(HW検査を省略できない)
VMIからSysPrep済みかは分からないので、分かりやすいVMI名をつけないとハマる

windowsサーバで英語キーボードと認識される
結局解決策は分からず。。。
やっていること
  • 言語に日本語追加
  • Dateを日本に変更
  • Localeを日本に変更
  • 標準キーボードのドライバを106/109(Ctrl+Eisu)に変更
  • Mac RDPとMac RDP Betaの両方とも試す

waagent
Sysprepと同様な機能を持つLinuxインスタンス向け構成管理ツール
sudo waagent -deprovision

VMI
Virtual Machine Image
旧Azureポータルだと少し分かりづらかった。
左カラム・VIRTUAL MACHINES → 右ウィンド・IMAGES

VMIからのWindowsインスタンスの作成
Tier / Size※ / ユーザ・PW / Cloud Service = 変更可能
Region / Storage Account = 変更不可

Immutable Infrastructure / Disposal Infrastructure
本番環境のサーバ環境設定を継続的に変更を加えるのではなく、
開発環境で新しい環境を毎度作り、それを入れ替える形で都度展開するインフラの保守方式

99.95%のSLA
仮想マシン2台以上で冗長構成すると言う条件で99.95%

Scaling Up
再起動を伴います。構成変わるから、しょうがないっすよね。
また、再起動に伴い、DHCPも振り直されます。

変更方法:インスタンスの詳細情報から、CONFIGUREタブでTier / Sizeを変更できます

Windows ServerのID
Local Security IDとDomain Security IDがあるみたいです
ここら辺は別途確認します。Win Server全然使ったことないからなぁ。。。

Intel® Xeon® Processor E5-2660 (20M Cache, 2.20 GHz, 8.00 GT/s Intel® QPI)
Intel Xeon
はい、サーバ周りも強くないので、Xeonを調べました。
下記ページを参考にさせていただきました
CPUにXeonを使う意味や違いを初心者向けに解説
プロセッサだけでなく、ECC対応のメモリがないとパフォーマンスを引き出せないんですね

リソグラフィー(Lithography)
半導体の製造技術

ECC対応メモリ
Error Check and Correctですか。
64bitごとに8bitの検出用データを付与して、
1bitは訂正、2bit以上でも検出はできる

障害ドメイン
物理的サーバラックに近い

更新ドメイン
アプリケーションの更新の単位

可用性セット
冗長構成を組むために使用する論理グループ

Affinity Group
以前は使用されていた機能らしい
当初は、複数のサーバを立てた際に、物理的に遠い
(と言ってもデータセンター内でしょうが、、、)所に配備されていたそうです。
そのため、Affinity Groupと可用性セットを組み合わせることで、
「なるべく物理的に近い、異なる障害ドメインに複数のサーバを配備」することができたらしい。
今はAffinity Groupを設定しなくても、上記のように計らってくれる。
ちなみに、設定は、旧ポータルのSETTINGS → AFFINITY GROUPSに残っています。

END POINT
Stand Alone / Load-Balanced Set

動いているインスタンスのシリーズ変更
試してみましたが、できないみたいです

ATAディスク
ATA / IDE / PATA はどれも同じものを指している。
SerialよりParallelの方が早そうなものですが、同期処理がオーバーヘッドになるそうです。
SATAがSerial-ATAだとは覚えていたが。。。

TierがBASICだと可用性セットが使用できない
書いているそばから忘れていた
Load-Balanced Set End Pointが作成できなくてはまっていましたが、
TierがBASICだとロードバランサーが使えませんでした。

Probe Protocol
HTTP or TCP
正常性確認のプロトコル
プロトコルに応じたポートとURLを指定する。
インターバルと回数で、「障害からダウン認定」と「復帰から正常認定」の最大時間が決まる

iSCSI
IPネットワークでネットワークドライブを使用するためのプロトコル

データ共有方法
  • データベース接続
  • ファイル共有
  • ディスク共有
  • データ複製

ディスクの追加
デフォルトだとWindowsに対して1つしかディスクを追加できない?
追って確認します。

追記:問題なく実行できました。ディスク名変えてないという凡ミス。

ホストキャッシュ
Guest OSのキャッシュとは別に、Azure側でもつキャッシュ

Azure Virtual Machine Diskの容量制限
1 - 1023 GBまで

2017年1月8日日曜日

Perlの復習

Perlの復習
Perl入学式のサイトを参考にさせてもらいました。

2017/01/15 再開!


メモ

localeをjaにする
$ sudo apt-get install language-pack-ja
$ sudo update-locale LANG=ja_JP.UTF-8
Ubuntuだったのでupdate-localeを使ってja_JP.UTF-8に設定する。
LAUNGUAGEとLC_ALLだけunsetだったので、手動で設定
$ export LC_ALL="ja_JP.UTF-8"
$ sudo export LANGUAGE="ja_JP.UTF-8"

perl -v
v5.18.2

nautilus
Ubuntuのファイルマネージャ
Ubuntuのデスクトップは使わないので、縁がない。。。

open
Mac OS XのFinderを開くコマンド

Encodeモジュール
文字列のエンコードを処理するモジュール

Perl5のバージョニング
5.nが偶数=安定版、奇数=開発版

サポート対象
最新版の1つ前の安定板までが基本的にサポート対象

Ubuntuのバージョン確認
lsb_release -r

CPANの読み込みでメモリ不足でuntarできない
$ sudo cpan
cpan[1]> upgrade

Running install for module 'Digest::SHA'
Running make for M/MS/MSHELOR/Digest-SHA-5.96.tar.gz
Fetching with HTTP::Tiny:
http://ftp.neowiz.com/CPAN/authors/id/M/MS/MSHELOR/Digest-SHA-5.96.tar.gz
Fetching with HTTP::Tiny:
http://ftp.neowiz.com/CPAN/authors/id/M/MS/MSHELOR/CHECKSUMS
Checksum for /home/vagrant/.cpan/sources/authors/id/M/MS/MSHELOR/Digest-SHA-5.96.tar.gz ok
Uncompressed /home/vagrant/.cpan/sources/authors/id/M/MS/MSHELOR/Digest-SHA-5.96.tar.gz successfully
Using Tar:/bin/tar xf "Digest-SHA-5.96.tar":
Couldn't untar Digest-SHA-5.96.tar: 'メモリを確保できません'
Package seems to come without Makefile.PL.
  (The test -f "/home/vagrant/.cpan/build/MSHELOR-ENMFP5/Makefile.PL" returned false.)
  Writing one on our own (setting NAME to DigestSHA)
  Had problems unarchiving. Please build manually
Running make test
  Make had some problems, won't test
Running make install
  Make had some problems, won't install

vagrant上のUbuntuへのメモリ割り当ての増加
Vagrantfileのvb.memory = "1024"の行のコメントアウトを外す
$ free
             total       used       free     shared    buffers     cached
Mem:       1017772     236296     781476        988      11732     104264
-/+ buffers/cache:     120300     897472


$  cat /proc/meminfo | grep MemTotal
MemTotal:        1017772 kB
設定する前のメモリ容量を確認し忘れていましたが、
とりあえず解決した。

perldoc モジュール
モジュールのヘルプを見れる

#!/usr/bin/env perlについて考える
自分の環境だと/usr/bin/perlなので、なんで/usr/bin/envなんだったかと調べた。
「env コマンド」で環境変数でコマンドを実行
/usr/local/binや/usr/bin/に固定すると汎用性が下がるからということですね。

use strict;
文法を「厳しく」チェックする

use warnings;
不適切なコーディングに対して警告を出す。

use Data::Dumper;
Dumperモジュールの使用
print Dumper $var;

Ubuntuでのperlアップグレードに手こずる
CPANでのupgaredeに失敗し、最終的にperlbrewというツールでアップグレードできました。
作者に感謝。こちらのサイト(perlbrewで構築するモダンなPerl環境)を参考にさせてもらいました。
$ curl -kL http://install.perlbrew.pl | bash
$ echo "source ~/perl5/perlbrew/etc/bashrc" >>  ~/.bashrc 
$ source ~/.bashrc 
$ perlbrew available # 利用可能バージョンの確認
$ perlbrew install  perl-5.24.0 # 5分ぐらいかかった
システムperlを上書いてしまうみたいです。

Perlの変数
知っているつもりだけど、改めて記載
  1. スカラ変数:$
  2. 配列:@
  3. 連想配列:#
my $hoge;
$hoge = "hoge";
# my $hoge = "hoge";

**
ベキ乗数の計算。左結合 3**4 => 3 * 3 * 3 * 3 => 81

インクリメント
後置も前置もオッケー

STDINのいい感じの処理
my $stdin = &let;STDIN>;
  chomp($stdin);
  @stdin = split(/,/,$stdin);
また、「すぐわかるPerl」深沢千尋さん著には次のいい感じのコードがあった。
while( <STDIN> ) {
  print ;
}
$_が省略されている。$_には最後に評価したものが入るみたいです。

数値と文字列の比較演算子が違う
==(数値), eq(文字列)
逆で覚えていた。。。

数値と文字列を比較した場合
数値の比較演算子(==, >=など)で、数値と文字列を比較した場合、
文字列は数値として扱われる。その文字列の左から数字が続いている範囲の数値とする。
'1234五'などの場合、1234として扱われる。左側に数字がなければ('一2345'など)、ゼロとして扱われる。
「−1234 + 5 = 5」となります(※−は「マイナス」を変換した記号で、文字のため、−1234がゼロと認識されてしまう)
また、実行時に警告が出ます。
(Argument "hoge" isn't numeric in addition (+) at calc3.pl line 10, line 2.)

一方、文字列の比較演算子で、数値と文字列を比較した場合は、
警告も出ず、数値を文字列に自動変換して比較できます。

Perlの偽値
  • undef
  • 空のリスト
  • 数値のゼロ
  • 文字列の0と""(空文字)

Perlの真値
Perlの偽値「以外」

elsif
elsifなんです。switchないそうです。
調べてみると、5.18からgivenという構文が使えるそうですね。
参考:[[Switch]] メモとかメモのようなものとか(By ルーキーの中のひと)
ただ、今の所givenはexperimental(試験中)扱いで使用時に警告が出ます。

say関数
最後に改行をつけて標準出力する関数。
use feature ':5.18';のようにfeatureプラグマをつけないと使用できない。

chomp()
端のスペースを除く。
値を返すのかと思っていて、$var = chomp();と間違った使い方をしてた。

and, &&, or, ||
全て短絡評価する。違いは優先順位。&&,||は、and, orより優先度が高い。
代入や分岐構文として使うときに注意

評価式の左項に、変化する値を、右項に(変化することが少ない)評価基準を置く
リーダブルコードに載っていて知っていたけど、逆で書き出した自分がいました。

@
arrayのa

配列の要素を取得したらスカラー変数です
一意に決まるので。

my @nums = ( 1, 2, 3 );
配列の初期化。各要素は文字列と数値を混ぜてオッケー。 配列を入れてもオッケー。

my @nums = ( 1..3);
範囲演算子..により簡潔に書けます。
小さい方から左に書く。逆に書くと要素は空になる。

for my $num ( @nums )
foreachがあっさり書ける。

my @nums = qw(1 2 3 4 5);
空白文字で区切り、配列に格納する
デリミッター(区切り文字)は、他の記号文字に変更可能。
qw@1 2 3 4 5@も有効
区切り文字を変えることで、qw内の途中にカッコが含まれていても問題なくなる。
もしくはエスケープすることで、不本意な区切りを回避できる。

split($str, $target);
$strで$targetを区切った配列を返す。

join($str, @array)
@arrayを$strで連結させた文字列を返す

シジル(sigil)
変数の前につく記号のこと

sort
文字列ソート:sortのみ, あるいはsort { $a cmp $b } @array
数値ソート :sort { $a <=> $b } @array
※ $a, $bはsortのために予約されているので、「他の部分で使ってはいけない」

=>
ファットコンマ演算子、というらしい

$hash{name}
ハッシュの値の取り出し、nameキーの値を取り出す。

my %hash = ('key1', 'value1', 'kye2', value2);
key, value,...と言うように配列と同じように仮想配列を初期化することもできる

ダックタイピング
weblio辞書
あるインターフェースの実装を宣言していなくても、そのインターフェスのメソッドを
全て実装しているクラスは、そのインターフェスを実装しているとみなす。

リファレンス
変数の参照のこと
スカラー変数に格納する。
既存の変数、配列、連想配列の前に\(バックスラッシュ)をつけることで、リファレンスを作成できる

["a", "r", "r", "a", "y"]
配列の実体を作らずに連想配列のリファレンスだけ作る方法
無名配列とも言う。

{ key => value};
連想配列の実体を作らずに、連想配列のリファレンスだけ作る方法
無名ハッシュとも言う。

配列リファレンスを、配列として使う
@array = ("hoge", "fuga" );
$array_ref = \@array;
print ${$array_ref}[0]; # hoge
{$array_ref}で配列して扱うことができるようになる
print $arra_ref->[0] # hoge
ともかける

要素数の取得
@array, %hashでもコンテキストによっては要素数を取得できる
scalar @arrayで確実
$#arrayで最後の添え字を取得

grep { /regex/ } @array;
パターンマッチしたものを配列で返す

ハッシュのforeach
foreach my $key(keys(%array)){

デリファレンス
戻すデータ構造に対応するシジルを付与する
$$ref
@$ref
%$ref

ハッシュへの追加
$hash{key} = value;
配列と混同してしまし、pushしている自分がいました。。。

ハッシュの値のソート
foreach my $key (sort { $ranks{$b} <=> $ranks{$a} } keys %ranks){

2017年1月7日土曜日

Git / メモ

GitについてWebで調べていたら、面白い発見がありました。


メモ

$ git shortlog -ns
コミッターごとのコミット数を降順で表示されます

$ git note
注釈をつけることができます

$ git citool
GUIでgitを扱えるサブコマンドなそうな。。。
まぁそういうのがあるんだっていうだけで、実際はSourceTreeとかを使いますがね。

git show-branch
わかりやすくブランチのコミット履歴を表示する

git bisect
テストスクリプトを実行して、問題があるコミットを特定するのに使える。

git bisect