JSゆるふわめも

がっこうでべんきょうしたことをめもがきしてます

メモ

文と式

    • 値を持たない
    • 値を持つ

Goのgc

最後にGCされた時に確保されたメモリの使用量の倍になった時にGCが走る

  • ex) gcした結果1Gの使用量 -> 2Gの使用量になったらgcが走る
  • GCのチューニングは可能。停止することも可能

なぜMapが毎回ランダムな値を返すのか?

  • Keyを取得して意図したValueを取得するために、Keyを明示的にソートすることを強制させるため?

サーバにアクセスした際、handlerが二回呼ばれている気がする

  • ブラウザが二回アクセスしている(最初にfavconを取りに行ってる)

公開される名前(基準は英単語の大文字・小文字だけなのか。記号・日本語だとどうなるか。)

goにおけるリテラル宣言

  • javaの場合「100」と書くと、int 100のリテラル宣言
  • goの場合、型が定まっていないintっぽい型の定数宣言として扱われる

heap, stackの割つけ

  • コンパイラが変数のスコープを見てheapにとるか、stackにとるか決定する

heapを使用する場合:変数の生存期間が関数を抜けてるため

func f() *int{
    v := new(int)
    return v
}

stackを使用する場合

func f() {
    v := new(int)
    ...
}

new

パラメータの型文メモリを確保して、ゼロ値を埋めてそのアドレスを返す

実行順序の定義 参照:Order of evaluation

Order of evaluation
At package level, initialization dependencies determine the evaluation order of individual initialization expressions in variable declarations. Otherwise, when evaluating the operands of an expression, assignment, or return statement, all function calls, method calls, and communication operations are evaluated in lexical left-to-right order.

For example, in the (function-local) assignment

y[f()], ok = g(h(), i()+x[j()], <-c), k()
the function calls and communication happen in the order f(), h(), i(), j(), <-c, g(), and k(). However, the order of those events compared to the evaluation and indexing of x and the evaluation of y is not specified.

a := 1
f := func() int { a++; return a }
x := []int{a, f()}            // x may be [1, 2] or [2, 2]: evaluation order between a and f() is not specified
m := map[int]int{a: 1, a: 2}  // m may be {2: 1} or {2: 2}: evaluation order between the two map assignments is not specified
n := map[int]int{a: f()}      // n may be {2: 3} or {3: 3}: evaluation order between the key and the value is not specified
At package level, initialization dependencies override the left-to-right rule for individual initialization expressions, but not for operands within each expression:

var a, b, c = f() + v(), g(), sqr(u()) + v()

func f() int        { return c }
func g() int        { return a }
func sqr(x int) int { return x*x }

// functions u and v are independent of all other variables and functions
The function calls happen in the order u(), sqr(), v(), f(), v(), and g().

Floating-point operations within a single expression are evaluated according to the associativity of the operators. Explicit parentheses affect the evaluation by overriding the default associativity. In the expression x + (y + z) the addition y + z is performed before adding x.

結果変数

func foo() (x, y int) {
    //x, yはfooのローカル変数0値に初期化されている
    return 100, 150 // x = 100, 150
}

//double関数が返す値を結果変数resultを用いてロギング
func double(x int) (result int) {
    defer func() { fmt.Printf("return %v", result)}
    return x + x
}

goでクロスコンパイル

ブラウザ操作を自動化するgoライブラリ

agouti

goのパッケージインポート

イメージ

go run はこれらをバックで実行させているに過ぎない。 各ツールをカスタマイズすることで(普通はしないけど、、、googleはしてる)、環境に合わせたgoの実行環境を用意することができる

レキシカルスコープの落とし穴

プログラミング言語Go P160参照

Go1.7からSSA(Statoc Single Assignment)が導入

Go1.7からSSAが導入された

便利なExample

Goには標準出力をテストするための便利な仕組みがある

テスト対象のコード

package main

import (
    "fmt"
    "os"
    "strings"
)

func main() {
    echo()
}

func echo() {
    fmt.Println(strings.Join(os.Args[0:], " "))
}

テストコード

package main

import "os"

func ExampleEcho() {
    os.Args = []string{"test", "test"}
    echo()
    // Output:
    // test test
}

func ExampleFailEcho() {
    os.Args = []string{"something", "toDo"}
    echo()
    // Output:
    // yatta
}

結果

--- FAIL: ExampleFailEcho (0.00s)
got:
something toDo
want:
yatta
FAIL
exit status 1
FAIL    _/Users/ono/dev/go/goRepo/ch01/ex01 0.007s

テストメソッド名をExampleで開始して、
//Output:コメントの次の行に 期待される標準出力の結果をコメントで記述すれば良い

// Output:
// 期待される標準出力

シンプルすぎて若干珍妙に感じてしまう

【Go学習記録】Goルーチンさわり

javaで言う所のthreadがチャンネルというらしい

大雑把な使用方法

func main {
   stringChanel := make(chan string)  //string型のデータを取り扱うチャンネルを生成する
   // intChanel := make(chan int) 
   go useStringChanel(stringChanel)  //スレッドの生成
   fmt.Println(<-stringChanel)      //チャンネルからデータの取り出し
}

func useStringChanel(ch chan <- string) {
 ...
   ch <- "Set string to chanel"
}

実践的な使用方法は後の章で紹介されるようなので、とりあえず今の所はこんなもんでいいか

大由彰(Akira Daiyoshi)というベーシスト

大由彰という偉大なベーシストがいた

唸るベースという表現がこれ程の似合うベーシストはいないと思っている

 

www.youtube.com

 

ただ、近年演奏している形跡は無く、ネットにも全く情報が見当たらない

現在でも演奏をされているのか、はたまたご存命なのか全く分からなかった

しかし、先日遂に大由彰さんの近況を知ることができた

 

大由彰さんとトリオを組まれていた山本剛さんのライブに行った際に、

山本さんに大由彰さんの近況を質問してみたのだ

 

「大由彰さんは現在でも演奏をなされているのですか。そもそもご存命なのでしょうか」

「大由彰さんね。生きてるよ、だけど今はもうね演奏してないのよ」

「えっ、どうしてなんですか」

「脳を一回やっちゃってね。彼の演奏凄いでしょ。演奏してると興奮しちゃうの。それでまた脳をやるのが怖いからって止めちゃったのよ…」

「そういうことなんですか…」

 

ということらしい

現在は演奏を行っていないことは残念だったが、何よりも命あっての人生しょうがない

 

しかし、今も演奏をなされていたらきっと日本を代表するトッププレーヤーとして名を馳せていたのだろうなぁ

 

Javaプログラマーなら習得しておきたい Java SE 8 実践プログラミング

を読んでいて、BitSet.valueOfの使い方が良くわからなかったので調べた(正確には知ってる人に質問した)

 

上記書籍の良くわからなかった箇所は下記の部分

BitSet.valueOf(bytes).get(n) == ((bytes[n/8]) & (1<<(n%8))) !=0)

byte[] bytes = {(byte) 0b10101100, (byte) 0b00101000}

BitSet prime = BitSet.valueOf(bytes)

// {2, 3, 5, 7, 11, 13}

 

一体何がどーなって2, 3, 5, 7, 11, 13なんて数字が出てきたんだ…

 

valueOf

public static BitSet valueOf(byte[] bytes)
指定されたバイト配列内のすべてのビットを含む新しいビットセットを返します。

より正確には、
すべての n < 8 * bytes.length に対して
BitSet.valueOf(bytes).get(n) == ((bytes[n/8] & (1<<(n%8))) != 0) となります。

このメソッドは、BitSet.valueOf(ByteBuffer.wrap(bytes)) と同等です。

 

一見ややこしいが、javadocの定義によると

 

 1                                   0                      (n / 8)

7    6   5   4   3   2 1 0   7 6 5 4 3 2 1 0 (n%8)

15 14 13 12 11 10 9 8   7 6 5 4 3 2 1 0 (   n   )

0     0   1   0   1   0 0 0 | 1 0 1 0 1 1 0 0

 

n = 2の場合

1 = 00000001をn%8だけ左シフトすると00000100

byte[0] = 10101100

つまりこれらのビットのANDは

00000100

10101100

------------

00000100 != 00000000 (0)

BitSet.valueOf(bytes).get(2) == true

となり、2ビット目が立っていることが分かる。

 

単に、byte配列の値をベースにBitSetを初期化しているだけなんですね。

 

 

Base64メモ

A-Z(26)

a-z(26)

0-9(10)

+-,(2)

26 + 26 + 10 + 2 = 64文字

で表現されるエンコード方式

[変換前]Today is sunny

[変換後]VG9kYXkgaXMgc3Vubnku

 

で、何に使うの?

 

現在では、JSONなどで特殊文字を含まないように画像データをbase64エンコードしたり、Webページの表示の際にリクエスト数を減らすためにbase64エンコードした画像をhtmlにそのまま埋め込むなどの用途で用いられています

 

特殊文字 を汎用的な文字?に置き換えることによって、環境依存を避ける

リクエスト数を減らす?よく分からないのでググる

 

画像データをBase64エンコードして、取得した文字列を用いてインラインイメージ(HTML/CSSに埋め込まれたイメージデータ)化する。

つまり、10個の画像データがHTMLファイルとは別に管理されていた場合、それらにアクセスするために10回リクエストが飛ぶが、HTMLファイルに埋め込んでしまえば1度のアクセスで済むので高速にページが表示できるよね。といった話

 

当然というかイメージで大体わかると思うが、文字列に変換することでデータ容量は増える。根拠は調べてないが約37%増加する。

 

参考

qiita.com

文字列を変換する - オンライン文字列変換ツールを

HTTPリクエスト数削減テクニック1: インラインイメージ編 (1/3):CodeZine(コードジン)