【要約】マネジメントの基本 from エンジニアのためのマネジメントキャリアパス
上司に何を求めるか
1対1のミーティング
目的は2つ
1. 上司との間に人間的な「つながり」を作ること。
「部下にも私生活がある1個の人間」として扱う
2.「要検討事項について上司と1対1で話し合う定期的な場を設けること」
上司と責任を分かち合いたいテーマを掲げ、自身でお膳立てする
フィードバックと指導
- 部下を褒める時は人前で、叱る時は1対1
- ただし、人前で褒めらたくない人もいる
- FBはその場で即、が効果的
- 会社における地位や立場についての助言をもらう
トレーニングとキャリアアップ
- 昇進には直属の上司の後押しが必要不可欠
- どんな方面に照準を定めるべきか上司からアドバイスをもらう
管理のされ方
上司との関係づくりも上司任せにしない事が、職場生活、キャリアにも重要な姿勢。
自分が何を望んでいるのかをじっくり考える
何が自分を幸せにするのかは自分自身が負っている。
自分に対する責任は自分で負う
- 参加したいプロジェクトがあれば上司に頼む
- 伸ばすべき能力に関する助言など、FBは積極的に求める
- 昇給を望むなら意思表示を、昇進を望むなら何が必要かを探る
- 表明する事で、上司が公平さをもっていなくても、自分の立場を認識できる
上司も人の子
- ストレスを抱え、欠点もある
- 馬鹿げた事や、不公平な事もある
- 上司の仕事は部下のご機嫌取りではない。
- 助言を仰ぐのは相手への敬意と信頼を示す絶好の手法
上司は賢く選ぶ
上司次第でキャリアは大きく差がでる 有能な上司は社内での駆け引きの仕方を心得ている。
引用
Golang 制御文
if
基本
- 条件をかっこで囲む必要はない
- 三項演算子はサポートされていない
if x%2 == 0 { fmt.Println(x, "is even") }
変数の初期化
ifステートメント中に変数の初期化ができる。 スコープはifブロックの中だけになる。
if num := getnumber(); num < 0 { fmt.Println(num, "is negative") } else if num < 10 { fmt.Println(num, "has only one digit") } else { fmt.Println(num, "has multiple digits") }
switch
基本
Goではbreakが必要ない。
switch i { case 0: fmt.Print("zero...") case 1: fmt.Print("one...") case 2: fmt.Print("two...") default: fmt.Print("no match...") }
複数の式
switch city { case "Tokyo", "Kanagawa", "Chiba", "Saitama", "Tochigi", "Ibaraki": fmt.Print("Kanto") case "Aomori", "Akita", "Iwate", "Yamagata", "Miyagi", "Fukushima": fmt.Print("Tohoku") }
条件の省略
true値との比較に近い
switch { case r > 0.1: fmt.Println("Common case, 90% of the time") default: fmt.Println("10% of the time") }
forループ
基本
()が必要ない
for i := 1; i <= 100; i++ { sum += i }
条件、前後のステートメントは省略可能
while キーワードはないが、whileのような使い勝手となる。
for num != 5 { num = rand.Int63n(15) fmt.Println(num) }
for { if num = rand.Int63n(15);num == 5{ break } fmt.Println(num) }
defer 関数
defer ステートメントが含まれる関数が終了するまで、関数の実行が延期される
for i := 1; i <= 4; i++ { defer fmt.Println("deferred", -i) fmt.Println("regular", i) }
regular 1 regular 2 regular 3 regular 4 deferred -4 deferred -3 deferred -2 deferred -1
defer 関数の一般的なユース ケースは、ファイルの使用が終了したときにファイルを閉じること
func main() { f, err := os.Create("notes.txt") if err != nil { return } defer f.Close() if _, err = io.WriteString(f, "Learning Go!"); err != nil { return } f.Sync() }
panic 関数
プログラムを強制的にパニックにさせる。 Javaでいうthrow Exception
- すべての遅延関数呼び出しは、正常に実行される
- すべての関数から戻るまで、プロセスでスタックが続行される。
- その後、プログラムはログ メッセージを出力してクラッシュします。
panic("something went wrong")
recover 関数
recover() を使用すると、パニックの後で制御を取り戻すことができる 他の言語で言う、try/catch ブロックに近い
if r := recover(); r != nil { fmt.Println("Recovered", r) }
【要約】チームで意思決定プロセスを改善する5つのステップと4つの手法
概要
https://slack.com/intl/ja-jp/blog/collaboration/decisionmaking-process-team
チームで意思決定する際に役立つ手法の要約
優れた意思決定プロセスの条件
さまざまな人に入ってもらう。
多様性に富んだグループでは色々な見方が提示されるため、良い決定を下しやすい傾向にある。
意思決定できる状態で会議する。
情報共有のための会議と決定を下すための会議を区別する。
組織が意思決定のため会議を開いても、質問やディスカッション、説明といった情報共有を挟むと脇道にそれてしまう為。
意思決定プロセスを速めるには、鍵となる情報を事前にチームに共有しておき、アイデアや提案したい解決策などを用意して会議に臨むようお願いしておく。
肩書きは脇に置いておく
すべての人が気軽にアイデアや意見を出せるようにするには、役割や経験に関係なく全員の意見を平等に評価することが大切。そのために話し合いの基本ルールを設ける。
以下は一例
- ディスカッションを始める前に、すべてのメンバーが各自のアイデアを共有しておく
- 立場が上のメンバーは場を独占したりほかのメンバーに影響を与えたりしないよう、最後に話す
- 個人の能力や経験にかかわらず、出されたアイデアを平等に扱う
- 話を遮らずにしっかり聞く
意思決定プロセス改善のための 5 ステップ
- 解決策ではなく問題を明らかにする
- クリティカルシンキングを促進する
- 意見の不一致を想定・考慮する
- 現実的な締め切りを設定する
- 小さな決定は気にしない
解決策ではなく問題を明らかにする
問題を理解する枠組みを狭め過ぎてしまうと、ディスカッションが始まる前からその内容を限定してしまう。 問題をはっきりさせると同時に、解決策となりうるものに対しては広く考える
例
「顧客満足度アンケートを変えたほうがいいか?」
↓
「顧客のニーズをもっと理解するにはどうしたらいいか?」
クリティカルシンキングを促進する
人間は互いの意見に同意したがる傾向にあるため、最初に口を開く人(もしくは早い段階で支持を得た最初のアイデア)がグループでの決定に最も大きな影響を与える。言い換えれば、最初に提示された解決策は、たとえ一番良いものでなくても選ばれやすい。
これを避ける為にチームリーダーは「どうしてそう思うのですか?」や「その考え、または仮説を支持する証拠はありますか?」といった理解を深めるような質問をする
意見の不一致を想定・考慮する
Google CEOが掲げた優先事項
「『合意文化』を抑え、意思決定にアジリティ(機敏性)と効率性を取り戻すこと」
「すべての会議には必ず明確な意思決定者がいなければならない。意思決定者がいなければ決定が下されることもないため、会議を開くべきではありません」。
意思決定プロセスにおいて、決定を下すのがあまりにも遅いと、悪い決定をするリスクを減らすことができる一方、チャンスを逃してしまいかねない。
以下のエラーについて、それぞれ影響を比較する
- オミッションエラー (機会を逃すこと)
- コミッションエラー (悪い決定を下して会社に深刻な損失を与えること)
Google では合意を目指すのをやめてから、以前よりもアイデアを実行に移せるようになり、その結果わずか 90 日間で Google+ の機能を 100 以上リリースできました。
意思決定者は最終的に決定を下すが、反対意見を持つメンバーの懸念事項やアイデアを評価する必要がある
現実的な締め切りを設定する
達成可能な目標を設定することが大切
「なんとなく」ではなく、似ているプロジェクトにかかった時間に基づいて所要時間を算出する
比較対象となるプロジェクトが見つからない場合は 2 つのシナリオを用意する。
- 最良のシナリオ
- うまくいかない可能性のあるすべてのことを書き出した最悪のシナリオ。
実際の結果はその中間あたりになる
小さな決定は気にしない
すべての決定を詳細に検討する必要はない。
組織は大切な決定に時間を割くのではなく、あまり重要でない決定に必要以上の時間をかけている。
Amazon の CEO、Jeff Bezos 氏はそのために、すべての決定を 2 つのカテゴリーに分類している。
- 変更不可能な決定
- 変更可能な決定
Bezos 氏は、「変更可能な決定」 の事柄はなるべく早く決定すべきだと主張している。もし失敗しても、チームはそれから大切なことを学び、未来の決定に役立つ情報を得ることができる為
グループで意思決定するための4つの手法
- 先入観や決めつけを乗り越える
- 包括的なディスカッションをする
- 責任を割り当てる
- 決定を行動に移す
先入観や決めつけを乗り越える
「推論のはしご」:すべてのメンバーが自分の信じていることや推論に疑問を持つ
包括的なディスカッションをする
「ノミナルグループ手法」:チームのそれぞれが自分のアイデアや提案したい解決策を書き出すことで、メンバー全員が平等に参加しクリティカルシンキングができるようにする方法。書き出されたアイデアはグループで共有して話し合い、投票によってランクづけされる。これは、特定のメンバーがほかの人たちより多く話す傾向にあったり、勤続年数の少ない社員が意見を述べるのをためらったりする場合など、グループ内で不均等なパワーバランスが存在する場合に役立つ。
責任を割り当てる
「RAPID モデル」:意思決定プロセスのどの部分を誰が担当すべきかを明らかにする メンバーは次の 5 つの役割に分けられる
- 推薦(Recommend)
- 賛同(Agree)
- 実行(Perform)
- 情報提供(Input)
- 決定(Decide)
決定を行動に移す
「RACI チャート」:プロジェクトをタスクに落とし込み、各タスクにおける役割を関係者 1 人 1 人に割り当てる。役割には次の 4 つがある
- 実行責任者(Responsible)
- 説明責任者(Accountable)
- 相談相手(Consulted)
- 報告相手(Informed)
視覚的に理解できる表によって、誰が何の仕事を担っているのかがすぐにわかり、仕事量が均等に分配されていることがチームにも伝わる。
Golang パッケージ
パッケージ
パッケージの作成
ディレクトリ構成
src/ foo/ message.go
パッケージソース
message.go
package foo var internalVar = "パッケージ内からしか読めません" var externalVar = "パッケージ外から読めます" func internalMessage() string { return "パッケージ内からのみ呼べる" } func Message() string { return "パッケージ外からも呼べる" }
public または private キーワードは用意されていない。 プライベートにするには名前の先頭を小文字に。 パブリックにするには、名前の先頭を大文字に。
ビルドの実行
$ go build
モジュールの作成
$ go mod init github.com/myuser/foo
src/ foo/ go.mod message.go
ローカル パッケージ の参照
準備
go.modの作成
go mod init mypackage
go.modの編集
# go.mod require github.com/myuser/foo v0.0.0 replace github.com/myuser/foo => path/to/foo
パッケージの使用
package main import "github.com/myuser/foo" func main() { println(foo.Message()) }
外部 (サードパーティ) パッケージの参照
package main import ( "rsc.io/quote" ) func main() { println(quote.Hello()) }
go.mod
module helloworld go 1.14 require ( rsc.io/quote v1.5.2 )
Golang 関数
関数定義
構文
func name(parameters) (results) {
body-content
}
例
package main func sum(x int, y int) int { return x + y } func main(){ sum := sum(2, 3) println("Sum:", sum) }
実行結果
$ go run main.go
$ 5
関数の戻り値に名前をつける
func sum(x int, y int)(result int) { result = x + y return }
複数の値を返す
func calc(x int, y int)(sum int, mul int) { result = x + y mul = x * y return }
ポインター渡し
package main func main() { foo := 5 update(&foo) println(foo) } func update(value *int) { *value = "10" }
実行結果
$ go run main.go
$ 10
MySQL 再帰クエリで階層構造のデータを一度に取得
準備
テーブル定義
CREATE TABLE `categories` ( `id` int(10) unsigned NOT NULL, `name` varchar(45) NOT NULL, `parent_id` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`id`), FOREIGN KEY (`parent_id`) REFERENCES `categories` (`id`) ON DELETE SET NULL ) ENGINE=InnoDB;
検証データの挿入
INSERT INTO `categories` (`id`, `name`, `parent_id`) VALUES (1, "Fashion", NULL), (2, "Mens", 1), (3, "Ladies", 1), (4, "Tops", 2), (5, "Shirts", 4), (6, "Food", NULL), (7, "Water", 6), (8, "Meet", 6), (9, "Sweets", 6) ;
データの取得
構文
with recursive R as ( select anchor_data -- 取得1行目ここが起点となる union [all] select recursive_part -- 取得2行目以降、ここが再帰となる from R, ... ) select ... -- 実行結果の取得
実行
ついでに1行目のクエリからの階層深度も取得できる形に。
WITH recursive child(depth, id, parent, name) AS( SELECT 0, id, parent_id, name FROM categories WHERE categories.id = 1 UNION ALL SELECT child.depth + 1, categories.id, categories.parent_id, categories.name FROM categories, child WHERE categories.parent_id = child.id ) SELECT depth, id, parent, name FROM child ORDER BY depth ;
結果
+-------+------+--------+---------+ | depth | id | parent | name | +-------+------+--------+---------+ | 0 | 1 | NULL | Fashion | | 1 | 3 | 1 | Ladies | | 1 | 2 | 1 | Mens | | 2 | 4 | 2 | Tops | | 3 | 5 | 4 | Shirts | +-------+------+--------+---------+