ITと雑記とド田舎と

ド田舎在住エンジニアがIT備忘録と雑記を書くブログです

「科学的な適職」 鈴木 祐 著

本の紹介

サラリーマンなら誰しもある程度は思うことだと思いますが、このまま今の職場に居ていいのかという月並みな悩みを最近よく考えており色々、自分の考え方を見直す意味で読んでみました。

前評判から単なる職業探しを目的とした本ではないと思っていたのですが、印象通りの本でした。
適職を導き出すとタイトルにありますが、本の内容は多くの研究結果から仕事という点において幸福度・満足度を上昇させる方法について書かれている本です。

構成としては

  1. 職業選択の基準についての誤解
  2. 幸福度を上昇させる要因
  3. 職場の8大悪
  4. 意思決定の方法
  5. 職場の評価方法と仕事方法の再構築

以上について書かれています。

職業探しという観点を基準にした内容ではありますが、働く中で自分のおける環境を最適化する方法について非常に論理的・統計学的に解説された本でした。
前半は職業選択の誤解について書かれており、続いてこれまで認識が間違っていたのなら、何に重点をおいて仕事を選べばよいのかを学ぶことができます。 続いて職業探しについて意思決定の方法を具体的な手法を落とし込んで説明されています。 最後に職場の評価方法と自分の仕事のやりがいを向上させる方法を、こちらも手法を用いて解説されていました。

内容について

第1章の「幻想から目覚める」から少し内容を紹介したいと思います。 一般的な職業選択の誤解について書かれており、本書を読んでいて最も印象に残った内容でした。

本章では誤解について7種類紹介されているのですが、私の場合その中の1つ「業界や職種で仕事を選ぶな」に完全にはまっていることに気づきました。
わたしは大学で情報工学を専攻しており、そのままIT業界に就職しました。その時点では一番自分にとってやりたいことがIT業界だったため就職したのですが、本書を読んで冷静に考えてみると単に他の可能性を排除していただけということに気づきました。
第4章で人は時間やお金を書けたことにこだわってしまうという「サンクコスト」について書かれているのですが、私の場合もこれに強く当てはまっていると感じました。
私は日頃から視野が狭くアイディアが中々出てこないと思うことが多いのですが、これは狭い業界のことしか知らず、そこにこだわっているのも要因の1つではないかと気づくことが出来ました。 このほかにも直観と乖離している内容が多く、まさに幻想から目覚めることが出来る内容だと思います。

感想

就職活動や転職活動の前段階として読むのにとても良い本だと思います。 一般的な誤解を持ったままより、この本を読んで誤解を解消してから行動したほうが上手くいきやすいと思います。

それだけではなく、日々の行動の中にまで落とし込める考え方が多く書かれていました。職業選択の意思決定で紹介されているプロコン分析やマトリックス分析はそのまま他のことにも応用できます。意思決定手法として紹介されているプレモータムやイリイスト転職ノートも同様です。
紹介されている手法をいきなりすべて使ってみるというのは難しいかもしれませんが、まずはどれか一つを意識しなくても使いこなせるようになれば意思決定による成功率を上げられると思います。

科学的な適職 4021の研究データが導き出す、最高の職業の選び方

科学的な適職 4021の研究データが導き出す、最高の職業の選び方

「やりぬく人の9つの習慣 コロンビア大学の成功の科学」ハイディ・グラント・ハルバーソン著

「やりぬく人の9つの習慣 コロンビア大学の成功の科学」ハイディ・グラント・ハルバーソン著

今回はいつもと趣向を変えて年始に読んだ書籍の書評を書いてみたいと思います。

本の紹介

私は以前から心理学や人間行動学に興味があり、習慣改善について書かれているようなビジネス書を何冊か読んでいます。
そのような本の中でも特に心理学や人間行動学、脳科学に基づいて書かれている書籍は、各分野の研究結果をエビデンスとして書かれているので統計的に見ても信頼性・実用性に非常に優れていると感じています。

本書もそのような書籍でありメンタリストのDaiGoさんが動画で紹介されていたのをきっかけに購入しました。

さて、本の内容について一言でいうと「やる気を維持して目標を達成するにはどうしたらいいか」というものです。
また、この本の特徴の1つはページ数が非常に少ないという点です。私は電子書籍で購入しましたが紙版で120ページ程のようです。
余計な内容を削ぎ落してとても簡潔にまとめられており、短時間で読了することができます。
私はあまり本を読むのが速いほうではないのですが、内容をまとめながら読んでも2時間ほどで読み終えることが出来ました。 短時間でやる気を維持する方法を知りたいという方にもとてもお勧めできます。

内容について

本書は目標を達成するにはどうしたらいいかという切り口から始まります。
続いて目標に対する行動計画の作り方を説明し、日々の行動の中でどのように目標に臨めばやる気を維持することができるのか。また、目標を達成する中でどのように自身を成長していけば良いのか説明がされていきます。

例えば第4章には目標に臨む上での心構えとして

地に足の着いた「現実的な楽観性を持つ」

と書かれています。
これは目標は達成できると信じなければならないが、「簡単に達成できる」と思うのではなく具体的なプランを建てることで「正しい方法で努力をすれば達成できる」と思うことが重要という意味です。
このような内容が心理学の研究結果と共に書かれています。

意識さえすれば誰でも行動に移せるような内容ばかりで、効果を数字で示してあるので非常に説得力があるように感じました。

 感想

私がこれまで読んだ習慣改善について書かれていた書籍は、具体的な方法よりも内容や事例について多く書かれているものが多かったのですが、本書は目標達成の方法について分かりやすく簡潔にまとめられていました。
明日からでも実践することが出来るような内容で、やる気を目標達成につなげる具体的な方法を知ることが出来ました。
今年中に達成したいと考えている目標があるので、すぐにでも実践してみようと思っています。
大きな目標を持たれている方で、モチベーションの維持について少しでも気になっていることがある方は読まれてみてはいかがでしょうか。

A Tour of Go Exerciseの解答まとめ

A Tour of Go Exerciseの解答まとめ

A Tour of Goを終えたのでExerciseの解答を残しておきます。
すべて自力で解答しています。
答え合わせはこちらを参考にさせていただきました。

Exercise: Loops and Functions

package main

import (
    "fmt"
    "math"
)

func Sqrt(x float64) float64 {
    z := 1.0
    for dz := z; math.Abs(dz) > 1e-12; z -= dz {
        dz = (z*z - x) / (2 * z)
        fmt.Println(dz, z)
    }
    return z
}

func main() {
    fmt.Println(Sqrt(10))
    fmt.Println(math.Sqrt(10))
}

Exercise: Slices

package main

import "golang.org/x/tour/pic"

func Pic(dx, dy int) [][]uint8 {
    pic := make([][]uint8, dy)
    for y := range pic {
        pic[y] = make([]uint8, dx)
        for x := range pic[y] {
            //pic[y][x] = uint8((x + y) / 2)
            pic[y][x] = uint8(x * x)
        }
    }
    return pic
}

func main() {
    pic.Show(Pic)
}

Exercise: Maps

package main

import (
    "strings"

    "golang.org/x/tour/wc"
)

func WordCount(s string) map[string]int {
    words := strings.Fields(s)
    result := make(map[string]int)
    for _, word := range words {
        result[word]++
    }
    return result
}

func main() {
    wc.Test(WordCount)
}

Exercise: Fibonacci closure

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    num1, num2 := 0, 1
    return func() int {
        num := num1
        num1, num2 = num2, num1+num2
        return num
    }
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}

Exercise: Stringers

package main

import "fmt"

type IPAddr [4]byte

func (ip IPAddr) String() string {
    return fmt.Sprintf("%v.%v.%v.%v", ip[0], ip[1], ip[2], ip[3])
}

func main() {
    hosts := map[string]IPAddr{
        "loopback":  {127, 0, 0, 1},
        "googleNDS": {8, 8, 8, 8},
    }
    for name, ip := range hosts {
        fmt.Printf("%v: %v\n", name, ip)
    }
}

Exercise: Errors

package main

import (
    "fmt"
    "math"
)

type ErrNegativeSqrt float64

func (e ErrNegativeSqrt) Error() string {
    return fmt.Sprintf("cannot Sqrt negative number: %v", float64(e))
}

func Sqrt(x float64) (float64, error) {
    if x < 0.0 {
        return x, ErrNegativeSqrt(x)
    }

    z := 1.0
    for dz := z; math.Abs(dz) > 1e-12; z -= dz {
        dz = (z*z - x) / (2 * z)
    }
    return z, nil
}

func main() {
    fmt.Println(Sqrt(2))
    fmt.Println(Sqrt(-2))
}

Exercise: Readers

package main

import "golang.org/x/tour/reader"

type MyReader struct{}

func (r MyReader) Read(b []byte) (int, error) {
    for i := range b {
        b[i] = 'A'
    }
    return len(b), nil
}

func main() {
    reader.Validate(MyReader{})
}

Exercise: rot13Reader

package main

import (
    "io"
    "os"
    "strings"
)

type rot13Reader struct {
    r io.Reader
}

func (rot rot13Reader) Read(b []byte) (int, error) {
    n, err := rot.r.Read(b)
    for i, value := range b {
        diff := value - 'A'

        if (diff >= 0 && diff < 13) || (diff >= 32 && diff < 45) {
            b[i] += 13
        } else {
            b[i] -= 13
        }

    }
    return n, err
}

func main() {
    s := strings.NewReader("Lbh penpxrq gur pbqr!")
    r := rot13Reader{s}
    io.Copy(os.Stdout, &r)
}

Exercise: Images

package main

import (
    "golang.org/x/tour/pic"
    "math/rand"
    "time"
    "image"
    "image/color"
)

type Image struct{}

func (img Image) Bounds() image.Rectangle  {
    return image.Rect(0, 0, 160, 120)
}

func (img Image) ColorModel() color.Model {
    return color.RGBAModel
}

func (img Image) At(x, y int) color.Color {
    return color.RGBA{uint8(rand.Intn(255)), uint8(rand.Intn(255)), 255, 255}
}

func main() {
    rand.Seed(time.Now().UnixNano())
    m := Image{}
    pic.ShowImage(m)
}

Exercise: Equivalent Binary Trees

package main

import (
    "fmt"
    "golang.org/x/tour/tree"
)

func Walk(t *tree.Tree, ch chan int) {
    if t.Left != nil {
        Walk(t.Left, ch)
    }
    ch <- t.Value
    if t.Right != nil {
        Walk(t.Right, ch)
    }
}

func Same(t1, t2 *tree.Tree) bool {
    ch1 := make(chan int)
    ch2 := make(chan int)
    go Walk(t1, ch1)
    go Walk(t2, ch2)
    for i := 0; i < 10; i++ {
        if <-ch1 != <-ch2 {
            return false
        }
    }

    return true
}

func main() {
    ch := make(chan int)
    go Walk(tree.New(1), ch)
    for i := 0; i < 10; i++ {
        fmt.Println(<-ch)
    }

    fmt.Println(Same(tree.New(1), tree.New(1)))
    fmt.Println(Same(tree.New(1), tree.New(2)))
}

Exercise: Web Crawler

package main

import (
    "fmt"
    "sync"
)

type Fetcher interface {
    Fetch(url string) (body string, urls []string, err error)
}

func (fetched *FetchedURLs) Crawl(url string, depth int, fetcher Fetcher) {
    if depth <= 0 {
        fetched.wg.Done()
        return
    }

    fetched.mux.Lock()
    if fetched.urls[url] {
        defer fetched.mux.Unlock()
        fetched.wg.Done()
        return
    }

    body, urls, err := fetcher.Fetch(url)
    if err != nil {
        fmt.Println(err)
        fetched.urls[url] = true
        defer fetched.mux.Unlock()
        fetched.wg.Done()
        return
    }

    fetched.urls[url] = true
    defer fetched.mux.Unlock()
    fmt.Printf("found: %s %q\n", url, body)
    for _, u := range urls {
        fetched.wg.Add(1)
        go fetched.Crawl(u, depth-1, fetcher)
    }
    fetched.wg.Done()
    return
}

func main() {
    fetched := FetchedURLs{urls: make(map[string]bool)}
    fetched.wg.Add(1)
    go fetched.Crawl("https://golang.org/", 4, fetcher)
    fetched.wg.Wait()
}

type fakeFetcher map[string]*fakeResult

type FetchedURLs struct {
    urls map[string]bool
    mux  sync.Mutex
    wg   sync.WaitGroup
}

type fakeResult struct {
    body string
    urls []string
}

func (f fakeFetcher) Fetch(url string) (string, []string, error) {
    if res, ok := f[url]; ok {
        return res.body, res.urls, nil
    }
    return "", nil, fmt.Errorf("not found: %s", url)
}

var fetcher = fakeFetcher{
    "https://golang.org/": &fakeResult{
        "The Go Programming Language",
        []string{
            "https://golang.org/pkg/",
            "https://golang.org/cmd/",
        },
    },
    "https://golang.org/pkg/": &fakeResult{
        "Packages",
        []string{
            "https://golang.org/",
            "https://golang.org/cmd/",
            "https://golang.org/pkg/fmt/",
            "https://golang.org/pkg/os/",
        },
    },
    "https://golang.org/pkg/fmt/": &fakeResult{
        "Package fmt",
        []string{
            "https://golang.org/",
            "https://golang.org/pkg/",
        },
    },
    "https://golang.org/pkg/os/": &fakeResult{
        "Package os",
        []string{
            "https://golang.org/",
            "https://golang.org/pkg/",
        },
    },
}

参照

ディレクトリ(フォルダ)とディレクトリ名のファイル自動生成

gist38937883cae62c9f9369d70a12616d6b

実行時引数にディレクトリ(フォルダ)名を与えて実行するとディレクトリとディレクトリと同名のgoファイルを作成してくれるpython3スクリプトです。 拡張子を変更すれば多用途にも流用できます。

Go(Golang)についてまとめてみる

Goについてまとめてみる

最近Golangを触り始めたので、備忘録兼自分の刷り込みようにまとめます。

マスコットキャラのGopher君がかわいい

f:id:kdn-1017-wttd:20191218231202p:plain
The Go gopher was designed by Renée French.

このデザイン個人的にツボです。ライセンスもCC BY 3.0という自由度の高いライセンスになっており、上の画像のように作者のRenée French氏のクレジットを掲示すれば自由に使用可能なのだそうです。

Golangの基本

それぞれについて分かる範囲で記述していきたいと思います。

2009年にGoogleで設計

2009年にGoolgeのロバート・グリーズマー、ロブ・パイク、ケン・トンプソンが設計した。 ロプ・パイク氏はカナダ出身のソフトウェア工学者でベル研究所UNIXを開発している。 ケン・トンプソン氏も同様にベル研究所UNIXの開発を行っており、そのほかにもB言語を設計。 後に同研究所に所属していたのデニス・リッチー氏がB言語にデータ型と新たな文法等を追加してC言語を開発している。(Wikipediaより)

GCPの対応言語のひとつでそのほか有名なサービスやOSSの開発に利用されています。
日本のサービスだとメルカリやクックパッド、Lineの一部ツールやサービス、OSSだとdocker,kubernetesが有名ですね。

コンパイル言語

コンパイル言語なので実行バイナリファイルが作られます。コンパイルも速いそうです。
もちろん実行速度も速いです。公式にも「表現に富み、簡潔で効率的」と書かれています。
まだ公式チュートリアルA Tour of Goを行っている途中ですがCやC++と比べて分かりやすい印象です。
私は学生の頃の研究はすべてC言語で書いていましたが、C言語の経験があれば抵抗なく始められると思います。

ガベージコレクション(GC)

JavaPythonなどの言語でも行われる自動的にメモリが開放される機能です。
私も知識がないので全く詳しい説明はできないですが、Goで採用されているのはConcurrent Mark & Sweepと呼ばれるシンプルなガベージコレクションだそうです。
Markでポインターをたどって使用されているオブジェクトにマークをしていき、Sweepでマークがついていないオブジェクトを空き領域にするという方式で、これをメモリの開放が終了するのと同時にマーキング処理を行うスレッドを並行して実行するためConcurret Mark & Sweepとのこと。

JavaGCはこれに加えてコンパクションや世代別GCと呼ばれる機能を持っています。
C言語などだとすべて自分でメモリ管理をしなければいけないので大変ですよね。組み込み開発だと必須スキルだと思います。
しかし、私の場合はそこまで意識する必要がない場合がほとんどなのでやはりGCはありがたいです。

メモリ安全

メモリエラーを回避するような実装がされているらしい。
バッファオーバーフローメモリリークなどをメモリ安全がないC言語などのように意識しなくても良いということだと思います。
ポインターは存在していますが、Cのようにポインタ演算ができないです。これもメモリ安全のための仕様でしょう。

構造的型付け

A Tour of Goを進めればわかるのかもしれないですが、よくわかっていません。
classが無いけどC言語の構造体のような物を利用して継承のようなことが出来るらしいです。
理解が進めば追記しようと思います。

並列処理が得意

  • GoroutineとChannelを使った並列処理。
  • CoroutineでもThreadでもProcessでもなく、複数Thread上に多重化されて実装されている。
  • Threadと比べて省メモリ(windows 1MB, Linux2MB, goroutin最小2048byte)
  • Threadよりも切り替えが高速。
  • main関数やGCもGoroutineで動いている。
  • Chanenelはメッセージパッシングを行うための物。多分Process間の共有メモリのような仕組みだと思います。
  • selsectを使って複数のchannelの値を同時に受け取れる。
  • close()でchannelを任意に閉じることができる。
  • Goroutineはtime.Afterでタイムアウトできる。
  • channelに一度に書き込める上限値を決められる。
  • goroutineの数を制限するGOMAXPROCSでCPUのコア数を指定するのが良い(Go 1.5以降だと自動で最適設定される)

ロスコンパイル

単一のソースコードからOS関係なくコンパイルが可能です。さらにWindowsLinuxのバイナリを生成するなどプログラミングしているOSを問わずコンパイルができます。32bit CPUで64bit CPUのバイナリを生成することもできるようです。

ロスコンパイル方法は以下

$ GOOS=linux GOARCH=amd64 go build hello.go

参照

python3備忘録 辞書型getメソッド

python3で辞書型のgetメソッドの備忘録です。

 getはkeyが存在しなければデフォルト値に設定した値を返すので、それを利用して新しい要素を追加したり、valueを更新したりできます。

 

gist4d26d112e29ea09075374f47a5eabb2a

 

 

AtCoder Beginner Contest 118備忘録 python3 reduce関数

先日参加した、AtCoder Beginner Contest118のC問題で最大公約数を求める問題があり、その際はじめてpython3のreduce関数について知ったので備忘録を兼ねてまとめます。

多分pythonを長く使ってる人にはとても基本的なところだと思います。

 

reduce関数

reduce関数は第1引数に関数、第2引数にリストやタプルを受け取り、リスト(タプル)すべての要素に対して第1引数に与えた関数を適用できる高階関数です。畳み込み演算が行えるのでfor文での繰り返し処理を置き換えたりできます。

 

私はC問題の解答はfor文で実装していたんですが、コンテスト後にTwitterを眺めているとreduceで簡単に書けるというつぶやきを見て調べてみました。

以下C問題での比較になります。for文版とreduce版で速度を比較してみました。速度ではfor文のほうが早そうですが、コードはreduceの方がすっきりしますね。臨機応変に使ってみようと思います。

 

gist6667a6189b3fcf88969c32aefb0b1f75