ENTRANCE

都内でエンジニアやってます。主にRubyとJavaを書いて遊んでる人のブログ。楽しくのんびりとがモットー。

ERROR! MySQL server PID file could not be found! は!?

リモートワークのある日の午後、

さて、シェルでも叩いてDBの初期データを入れようかなっとした瞬間。

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock'

動かないやん。さっきまでMySQL動いてましたやん。

とりあえず、MySQLサーバー止めてみよう

❯ mysql.server stop
 ERROR! MySQL server PID file could not be found!

いや、止まらんのかい。

なんかプロセス残っちゃってたかな...

❯ ps ax | grep mysql
19653   ??  S      0:00.04 /XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --XXXXXXXXXXXXXXXXXXXXXXXXXXX --XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
19875   ??  S      0:27.95 /XXXXXXXXXXXXXXXXXXXXXXXXXXXx --XXXXXXXXXXXXXXXXXXXXXXX --XXXXXXXx --XXXXXXXXXXXXXXXXXXXXXXXXX 
32692 s001  R+     0:00.00 grep --color=auto mysql

なんか色々残ってるな...

プロセスキルしてみる。

❯ kill -9 19653
❯ kill -9 19875

確認
確実にキルした。

❯ ps ax | grep mysql
32860 s001  R+     0:00.01 grep --color=auto mysql

もう一回止めてみる

❯ mysql.server stop
 ERROR! MySQL server PID file could not be found!

おい!!って、キルしたんだった😇

スタートしてみる

❯ mysql.server start
Starting MySQL
.............. SUCCESS! 

動いた!

一応止まるかも確認

❯ mysql.server stop
Shutting down MySQL
.. SUCCESS! 

問題なし!

シェルも動いてめでたしめでたし!

【Java】ソースをきれいに書くための空白と改行

全く同じコードでも、 改行や空白が綺麗に入ってるソースって、 見やすいよねってお話。

以下の7つのことを意識するとだいぶソースが読みやすくなると思います!

1. 制御構文の前後の空白
2. {の直前の空白
3. ,カンマ区切りの後の空白
4. 演算子前後の空白
5. 三項演算子の適度な改行
6. 処理の切れ目で空行を入れる
7. コンストラクタ改行する

1. 制御構文の前後の空白

/**
 * □ ポイントとなる空白を表してます。
 * ↩︎ ポイントとなる改行を表してます。
 */


if□(true)□{

}□else□{

}

try□{

}□catch□(Exception e) {

}

switch□(num) {
    case 1:

    case 2:

    default:
}

2. {の直前の空白

public void hoge()□{

}

3. ,カンマ区切りの後の空白

public void hoge(String foo,□String bar) {

}

4. 演算子前後の空白

Parson parson□=□new Parson(String name, int age);

if (hoge□==□null) {
}

5. 三項演算子の適度な改行(これは結構好みありそう)

String str = (hoge == "hoge")↩︎
    ? "hoge"↩︎
    : "hogehoge";

6. 処理の切れ目で空行を入れる

直前の処理とやることが変わったり、意味合いが変わる場合は適度に空行を入れてあげましょう。
コードの塊を作ってあげると、初見の人にとって読みやすいコードになります。

7. コンストラクタ改行する(かなり好き嫌いあるでしょう...)

複数人でコード修正を行うときに、コンフリクトしづらくなるので、
私が加入している案件では採用されています。

public class hogeObject {
    hogeObject(String a,↩︎
               String b,↩︎
               String c,↩︎
               String d,↩︎
               String e,↩︎
               String f,↩︎
               String h,↩︎
               String i,↩︎
               String j) {
    }
}

異論は歓迎です!

【Java】Enumとequalsと==と

Enumの比較は==を使えってことらしい。

こんにちは!かっつんです!

みなさん、Enum使ってますか?
私はEnum大好きです!

そんなEnumを比較するときは==を使えって聞いたことがあるから
なぜ==演算子を使うのか調べてみました!

1. equals == ==ってまじかよ。

Enumのequalsの内部実装をみてみた。

    /**
     * Returns true if the specified object is equal to this
     * enum constant.
     *
     * @param other the object to be compared for equality with this object.
     * @return  true if the specified object is equal to this
     *          enum constant.
     */
    public final boolean equals(Object other) {
        return this==other;
    }

いや、==じゃん。もろに。
==の勝ちですね!文字数も少ないし...

2. ヌルポ出るじゃん?

HogeEnum hoge = null;

if (hoge.equals(HogeEnum.HOGE)) { // NullPointerException出るね
}

equals使うとヌルポ出る可能性あるんですよね〜ってことで、==の勝ち。

HogeEnum hoge = null;

if (HogeEnum.HOGE.equals(hoge)) { // ヌルポ出ないね。
}

こんな感じで書けば、そもそもヌルポ出ないんだけど、
==なら
hoge == HogeEnum.HOGEでもHogeEnum.HOGE == hogeでも
ヌルポ出ないから勝ちです。

3. みんな大好きな型に守られる

String hoge = "hoge";

if (HogeEnum.HOGE.equals(hoge)) { // コンパイルエラー出ません。IDEが警告くらいは出してくれます。多分。
}


if (HogeEnum.HOGE == hoge) { // コンパイルエラーです。
}

==コンパイルエラー出してくれるんですよ。嬉しいですね。
==の勝ちです。

まとめ

JavaEnumの比較は、==を使った方が良い!

docs.oracle.com

【Gradle】Gradle4.Xから5.0にバージョンアップしてみた〜その2

Lombok動かない。

/src/api/SampleController.java:20: エラー: シンボルを見つけられません
        log.warn("hogehoge");
        ^
  シンボル:   変数 log
  場所: クラス SampleController

ほう。 IntelliJEnable annotation processing設定はチェックついてる。

build.gradleのdependenciesの確認

dependencies {
    providedCompile "org.projectlombok:lombok:${lombokVersion}"
}

lombok読み込んでるはず....
調べる。
intellij-support.jetbrains.com

やはり書き方がよくないらしい。

dependencies {
        implementation "org.projectlombok:lombok:${lombokVersion}"
        annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
}

動いた。

【Gradle】Gradle4.Xから5.0にバージョンアップしてみた〜その1

基本はドキュメントを読みましょう! gradle.org

task wrapper(type: Wrapper) {
    gradleVersion = "5.0"
}

動かない。。。

wrapper {
    gradleVersion = "5.0"
}

書き方変わったっぽいです。

他のタスク壊れてないかな

Execution failed for task ':swagger-codegen:taskName'.
> No value has been specified for this provider.

swagger(openapi) cogegen壊れたわ。
- 現在のバージョン: org.openapitools:openapi-generator-gradle-plugin:3.3.4

どうやらGreadle5系と仲が悪いらしい。参考

バージョンアップしてみよう。 3.3.4 -> 4.0.0(とりあえず)

BUILD SUCCESSFUL in 19s
2 actionable tasks: 2 executed
13:00:52: Task execution finished 'taskName'.

動いた。

project(':hogehoge').clean.execute()

動かない。

Gradel5系から削除されたのね。(4系の内に直すべき)
他にも削除メソッドあるようで 詳しくはドキュメントみてね

【GO】Golangの勉強を始めたから殴り書きのメモ~その4

つづき。 tour.golang.org

kattsundesu.hatenablog.com

Errors

  • goはエラーをエラー値で表現する。
package main

import (
    "fmt"
    "time"
)

// 構造体
type MyError struct {
    When time.Time
    What string
}

func (e *MyError) Error() string {
    return fmt.Sprintf("at %v, %s",
        e.When, e.What)
}

func run() error {
    return &MyError{
        time.Now(),
        "it didn't work",
    }
}

func main() {
  // err := run()
  // if err != nil {...} と同意
    if err := run(); err != nil {
        fmt.Println(err)
    }
}

Readers

package main

import (
    "fmt"
    "io"
    "strings"
)

func main() {
    r := strings.NewReader("Hello, Reader!")

    // strings.Readerを作成し、8byte毎に読み出しています。
    b := make([]byte, 8)
    for {
        n, err := r.Read(b)
        fmt.Printf("n = %v err = %v b = %v\n", n, err, b)
        fmt.Printf("b[:n] = %q\n", b[:n])
        // 末端まで行ったらbreak
        if err == io.EOF {
            break
        }
    }
}

Goroutines

  • Goのランタイムに管理される軽量なスレッド
package main

import (
    "fmt"
    "time"
)

func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    // これでごルーチンが実行される
    go say("world")
    say("hello")
}

Channels

package main

import "fmt"

func sum(s []int, c chan int) {
    sum := 0
    for _, v := range s {
        sum += v
    }
  // sumをcに送る
    c <- sum
}

func main() {
    s := []int{7, 2, 8, -9, 4, 0}

    // チャネルを生成する
    c := make(chan int)
    go sum(s[:len(s)/2], c)
    go sum(s[len(s)/2:], c)
    // チャネルcから値を受け取る
    x, y := <-c, <-c

    fmt.Println(x, y, x+y) // -5 17 12
}
  • Buffered Channels
package main

import "fmt"

func main() {
    // バッファの2ついたチャネルを作成
    // いっぱい渡すとバッファがつまる
    ch := make(chan int, 2)
    ch <- 1
    ch <- 2
    fmt.Println(<-ch) // 1
    fmt.Println(<-ch) // 2
}
  • Range and Close
package main

import (
    "fmt"
)

func fibonacci(n int, c chan int) {
    x, y := 0, 1
    for i := 0; i < n; i++ {
        // チャネル
        c <- x
        x, y = y, x+y
    }
    // クローズした後に追加するとpanic
    close(c)
}

func main() {
    // 10のバッファ付きチャネルを作成
    c := make(chan int, 10)
    go fibonacci(cap(c), c)
    for i := range c {
        fmt.Println(i)
    }
}
  • select
package main

import "fmt"

func fibonacci(c, quit chan int) {
    x, y := 0, 1
    for {
        select {
        case c <- x:
            x, y = y, x+y
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}

func main() {
    // チャネルを作成
    c := make(chan int)
    // チャネルを作成Part2
    quit := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println(<-c)
        }
        quit <- 0
    }()
    fibonacci(c, quit)
}

/**
0
1
1
2
3
5
8
13
21
34
quit
*/
  • Default Selection
package main

import (
    "fmt"
    "time"
)

func main() {
    tick := time.Tick(100 * time.Millisecond)
    boom := time.After(500 * time.Millisecond)
    for {
        select {
        case <-tick:
            fmt.Println("tick.")
        case <-boom:
            fmt.Println("BOOM!")
            return
        // 何にも該当しなければdefaultに入る
        default:
            fmt.Println("    .")
            time.Sleep(50 * time.Millisecond)
        }
    }
}

【GO】Golangの勉強を始めたから殴り書きのメモ~その3

つづき。 tour.golang.org

kattsundesu.hatenablog.com

Methods

  • メソッドの定義(レーシーバー)
package main

import (
    "fmt"
    "math"
)

type Vertex struct {
    X, Y float64
}

// Vertex型のレシーバーをもち、float64型の返り値をもつ、Absという名前の関数
func (v Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

type MyFloat float64

// typeでも定義できる
func (f MyFloat) Abs() float64 {
  if f < 0 {
        return float64(-f)
    }
    return float64(f)
}

func main() {
  v := Vertex{3, 4}
  // 呼び出す
  fmt.Println(v.Abs())
  
  // 呼び出す
  f := MyFloat(-math.Sqrt2)
    fmt.Println(f.Abs())
}
  • メソッドの定義(通常)
package main

import (
    "fmt"
    "math"
)

type Vertex struct {
    X, Y float64
}

// Vertex型を引数にもち、float64型を返り値にもつ、Absという名前の関数
func Abs(v Vertex) float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
  v := Vertex{3, 9}
  // 呼び出す
    fmt.Println(Abs(v))
}
  • ポインタレシーバ
package main

import (
    "fmt"
    "math"
)

type Vertex struct {
    X, Y float64
}

func (v Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

// ポインタレシーバ
func (v *Vertex) Scale(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}

// 変数レシーバ
func (v Vertex) Scale2(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}

func main() {

  v := Vertex{3, 4}
  // ポインタレシーバーを使う
  v.Scale(10)
  // vの値が変わってる
  fmt.Println(v.Abs()) // 50
  fmt.Println(v) // {30 40}
  
  g := Vertex{3, 4}
  // 変数レシーバを使う
  g.Scale2(10)
  // gの値は変わっていない
  fmt.Println(g.Abs()) // 5
  fmt.Println(g) // {3 4}
}
  • ポインタとメソッド
package main

import "fmt"

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Scale(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}

func ScaleFunc(v *Vertex, f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}

func main() {
    v := Vertex{3, 4}
    v.Scale(2)
    // ポインタを引数に渡す
    ScaleFunc(&v, 10)

    p := &Vertex{4, 3}
    p.Scale(3) // = (*p).Scale(3)
    // pはポインタ
    ScaleFunc(p, 8)

    fmt.Println(v, p)
}
  • パート2
import (
    "fmt"
    "math"
)

type Vertex struct {
    X, Y float64
}

func (v Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func AbsFunc(v Vertex) float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
    v := Vertex{3, 4}
    fmt.Println(v.Abs()) // 5
    // 引数はポインタではない
    fmt.Println(AbsFunc(v)) // 5

    p := &Vertex{4, 3}
    fmt.Println(p.Abs()) // = fmt.Println((*p).Abs()) // 5
    // 引数はポインタ
    fmt.Println(AbsFunc(*p)) // 5
}

-

package main

import (
    "fmt"
    "math"
)

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Scale(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
    v := &Vertex{3, 4}
    fmt.Printf("Before scaling: %+v, Abs: %v\n", v, v.Abs()) // Before scaling: &{X:3 Y:4}, Abs: 5
    v.Scale(5)
    fmt.Printf("After scaling: %+v, Abs: %v\n", v, v.Abs()) // After scaling: &{X:15 Y:20}, Abs: 25
}

Interfaces

package main

import "fmt"

// インターフェースの定義
type I interface {
    M()
}

type T struct {
    S string
}

// このメソッドを定義することで、
// 明示的に書かなくても、TはI(インターフェース)を実装していることになる。
func (t T) M() {
    fmt.Println(t.S)
}

func main() {
    var i I = T{"hello"}
    // 呼び出し
    i.M() // hello
}
package main

import (
    "fmt"
    "math"
)

// インターフェース
type I interface {
    M()
}

type T struct {
    S string
}

func (t *T) M() {
    fmt.Println(t.S)
}

type F float64

func (f F) M() {
    fmt.Println(f)
}

func main() {
    var i I

    i = &T{"Hello"}
    // インターフェースの中身は、値と具体的な型
    describe(i) // (&{Hello}, *main.T)
    i.M() // Hello

    i = F(math.Pi)
    describe(i) // (3.141592653589793, main.F)
    i.M() // 3.141592653589793
}

func describe(i I) {
    fmt.Printf("(%v, %T)\n", i, i)
}
package main

import "fmt"

// インターフェース
type I interface {
    M()
}

type T struct {
    S string
}

func (t *T) M() {
    // レジーバーがnilでも例外を引き起こさないようにメソッドを記述するのが一般的
    if t == nil {
        fmt.Println("<nil>")
        return
    }
    fmt.Println(t.S)
}

func main() {
    var i I

    var t *T
    i = t
    // ゼロ値はnil
    describe(i) // (<nil>, *main.T)
    i.M() // <nil>

    i = &T{"hello"}
    describe(i) // (&{hello}, *main.T)
    i.M() // hello
}

func describe(i I) {
    fmt.Printf("(%v, %T)\n", i, i)
}
  • Nil interface values
package main

import "fmt"

type I interface {
    M()
}

func main() {
    // 初期化はしない
    var i I
    // 実行される
    describe(i) // (<nil>, <nil>)
    // ランタイムエラー
    i.M()
}

func describe(i I) {
    fmt.Printf("(%v, %T)\n", i, i)
}
  • The empty interface
package main

import "fmt"

func main() {
    // 空のインターフェース
    var i interface{}
    describe(i) // (<nil>, <nil>)

    i = 42
    describe(i) // (42, int)

    i = "hello"
    describe(i) // (hello, string)
}

func describe(i interface{}) {
    fmt.Printf("(%v, %T)\n", i, i)
}
  • 型の検証
package main

import "fmt"

func main() {
    // インターフェースに元となる値を代入
    var i interface{} = "hello"

    // iがstring型を保持しているか検証
    s := i.(string) // stringでない場合は、panic!
    fmt.Println(s) // hello

    // iがstring型を保持しているか検証(bool値付き)
    s, ok := i.(string) // stringを保持すればTrue,保持しない場合はFalseでpanicは起きない。
    fmt.Println(s, ok) // hello true

    f, ok := i.(float64)
    fmt.Println(f, ok) // 0 false

    f = i.(float64) // panic
    fmt.Println(f)
}
  • Type switches
package main

import "fmt"

func do(i interface{}) {
    switch v := i.(type) {
    case int:
        fmt.Printf("Twice %v is %v\n", v, v*2)
    case string:
        fmt.Printf("%q is %v bytes long\n", v, len(v))
    default:
        fmt.Printf("I don't know about type %T!\n", v)
    }
}

func main() {
    do(21)      // Twice 21 is 42
    do("hello") // "hello" is 5 bytes long
    do(true)    // I don't know about type bool!
}