Go言語プログラミングエッセンス - Forkwell Library#27

Go 言語で楽しくなるシステム開発

自己紹介

  • mattnさん
    • Go言語プログラミングエッセンス著者
    • Google open source expert
    • Go歴 13年
    • Software Design
      • nostrの連載

概要

  • 簡単な説明
  • 特徴
  • Explicit is better than implicit
  • 非同期プログラミング
  • 最新のGo

Goについて

  • C言語の構文を意識しつつ、簡単な文法でコーディングできる
  • すでにいろんな会社で利用
  • プログラミング環境を改善する目的
    • C言語を設計した世界的エンジニアで知られる人が関わっている
    • Unixらしさ
  • 使用例
    • CLI
    • Webサーバー
    • バックエンド
    • 広告配信
    • ハードウェア制御
    • 機械学習

特徴

  • 静的型付けコンパイル言語
  • スタティックバイナリ
  • C言語風でありながら、GC
  • 非同期を簡単に扱えるランタイム

Explicit is better than implicit

  • 曖昧より明確のほうがいいよね
  • RobPike氏が良く言うこと
  • ex) error ハンドリング
  • Goは例外を扱わない
  • result typeを扱わない
  • errorが返ってきたら処理する
  • Goでバグを生み出さないコツ
    • すべてのerrorを明示的に対処し暗黙をなくす
      • deferをうまく使うことでエラーを減らす
    • errorを受け取ったら、処理を中断し、呼び出し元へ返す
    • →必然的にearly return
  • Goが優先したもの
    • 読みやすさ
      • 声に出して読めるくらい
    • 学びやすさ
    • 開発者が明示的に処理を中断させる
    • 予約語を増やさない
      • 複雑さを減らす
  • 開発者が意思決定するプログラミング

非同期プログラミングの良さ

  • ハードウェアが高性能化
  • 非同期は難しい
  • Goの仕組み
    • goroutine
    • channel
      • リレーのバトンのようなもの
  • 気をつけること
    • 並列と並行は違う
    • スレッドを増やすプログラミング言語
      • CPUコアに固定されない。空いたコアが次を担当する
        • CPUコアを有効に活用する
        • C言語でやると難しい
          • コンテキストスイッチのコストが発生してしまう
        • Goのスレッドは軽量なので、多く使っても大丈夫
    • スケールに対応しやすいのでクラウド向き

go 1.21でくるもの

  • min/max
    • 数値、文字列など
    • 実装するとinterface{}をつかうとコンパイルで気づけない
  • clear
    • mapやスライスを空にできる
      • スライスの長さが変わらない
    • 配列はできない
  • loopvar
    • まだ仮
      • 検証中
    • 並列で動かすときに、ループ変数が回り終わった状態で参照していしまうのの対処
  • pgo
    • コンパイラによるプロファイルベースの最適化
    • pprofの結果からホットパスをインライン化する
      • pprofの結果を読み込んでbuildすると最適化
  • slog
    • 構造化ログを出力できるように
    • ログレベルも設定
    • スレッドセーフ
    • 出力先変更可能
    • グルーピング
  • maps
    • 型パラメータを使ったmap操作関数
    • genericsができたので
    • key一覧、value一覧をとることができる
  • Slices
    • slice処理をかける
    • delete, insert, reverse, binarySearch, contains
  • wasi
    • wasmの実行環境がブラウザ依存だった
    • wasmを読み込んでgoで直感的にできるように
      • 標準ライブラリにほぼ対応
      • 利用できない/システムコールが必要なおの
        • net/http
        • os
    • エッジコンピューティングがしやすくなる

(youtubeアンケート、職務内容)

Q&A

  • Q. Goにジェネリクスが追加されて結構経ちましたがコミュニティではどういう扱いなのか知りたいです。普通に使って良いのか、なるべく使わないでおくべき機能なのかなどの肌感が気になっています。

    • A. まだあまりメインで使ってない。互換性がなくなることがある。
      • 最新2バージョンのサポートとはしている
  • Q. channelのバッファの数値を決める基準は何がありますか?

    • A. 詰まるタイミングが処理による。ブロッキングしてほしいときにスルーされるのが困る。バッファなしでやって徐々に増やすことがよさそう。通信料次第
  • Q. シェルで済むものをGoで書いて良かったと思った経験談とかあれば聞いてみたいです!

    • A. 環境変数がなかったときの処理。エスケープ文字の取り扱いが簡単。文字コードのトラブルを減らせる。
    • 型によるチェックで対応できる
  • Q. goroutineとchannel便利なのですが、エラーハンドリングが難しいです。goroutineにおけるエラーハンドリングのナレッジがあれば教えていただきたいです。

    • A. Contextを取り扱って実施することが多い。起動しっぱなしを止められる。
    • マルチスレッドに用途にあった機能
  • Q. Goの並行処理において、使用するCPUのコア数の上限はどこかで制御できるのでしょうか?

    • A. ソース上は決まっているはず。80コアでも動いた。
    • 使う数はGOMAXPROCSで指定できる
      • GO runtimeより
        • The GOMAXPROCS variable limits the number of operating system threads that can execute user-level Go code simultaneously. There is no limit to the number of threads that can be blocked in system calls on behalf of Go code; those do not count against the GOMAXPROCS limit. This package’s GOMAXPROCS function queries and changes the limit.

  • Q. Go言語で開発すべきプロダクトはどういうものでしょうか。

  • Q. 勉強用のコードリーディングにおすすめのOSSを教えてください。

    • A. k8sはあまりきれいでない。おすすめは標準ライブラリor標準ライブラリに携わっている人のコード
  • Q. Goでメモリを長期間大量に保持するプログラムを作ると、GCが世代別でないせいか、GC時のCPUスパイクが大きくて悩んでいます。GCのインパクトを緩和する良い方法は無いでしょうか。

  • Q. 近年のGoの変更の中ではGenerics(type parameter)が最も大きな変更点だと思いますが、その使い所や落とし穴などあれば教えてください。

    • A. Comparableな型での演算になるようにする。可変長の型パラメータはないので、複雑なことはできないようになっている
  • Q. 本業でGoを使っていて個人開発もGoを使おうと思っていますが、無料(もしくは少額)でデプロイできるサービスで、おススメはありますか? コンテナデプロイ出来るherokuがちょうど良かったのですが、有料化してしまい・・ (それでも一番コスパいいのかしら🤔)

    • A. 今日の時点ではfly.ioがおすすめ。VercelもGoアップロードできるが、実行時にコンパイルしてそう。
    • lambda, cloud runなどもあり
  • Q. ログライブラリzapは高パフォーマンスを売りにしていますが、ロギングライブラリにおいて高パフォーマンスはどのくらい重要すべきなんですか?slogを利用するときもそういう観点は注意した方がよいのでしょうか?

    • A. ログを入れて遅くなるのはよくある話。Goは後方互換性を重視している。slogはv1の間はそのままだと思われる。zapは壊れる可能性もある。どっちに投資するかはこのみ。
    • 自分の環境でベンチマークとってみるのがよい。
  • Q. close済みのchannelにwriteするとpanicになる仕様にときどき悩まされます。reader/writerが独立に動いて連携しにくい場合の良い設計があれば知りたいです。

    • A. goroutineの外側でwriteしようとしている。閉じるときとwrite処理を同じ場所で。contextで止めるように(上流で処理するように)
  • Q. おすすめのフレームワークを教えてください。

    • A. 本ではフラット。仕事ではechoで使っている。
    • 大きいものだとechoおすすめ
  • Q. golang v1では後方互換性が保証されているようですが、プロダクトで使用しているバージョンのアップデートに関して考慮すべきことはありますか?

    • A. 新しいインターフェースが入ったりしているので、新しいので合わせていくと良い。こまめにアップデートするとよい。
  • Q. Go言語をどのように習得してきましたか。

    • A. ver1の出る前に興味を持って、Windowsで動かせるようにcontribute。コミットごとを読む。標準ライブラリを読むのが良い。
  • Q. ネガティブ寄りの興味本位な質問ですみません。これまで一緒にGoに触れてきたエンジニアで、この人はGoに向いてないな、と感じた方はいらっしゃいますでしょうか?いる場合は、その方の考え方や言動のどの部分が向いてなかったのか、聞いてみたいです。

    • A. 他の言語でのやり方を入れようとすると汚いGo言語になりがち。
    • 人気のある言語の有名税
  • Q. 好きな Go の標準パッケージはなんですか

    • A. 一番読んだのでosパッケージ。OSごと
  • Q. slogのsは何のsですか?

    • A. structure
  • Q. Genericsが入ったことでgo generateはもうオワコンですか?もしくは、go generateのオススメの使い方を教えてください

    • A. go以外からGoを作るものなので、なくならない。
  • Q. テクニックの中でイチオシは何でしょうか?

    • A. 非同期がハマると面白い。

感想

  • Goでバグを生み出さないコツの"すべてのerrorを明示的に対処し暗黙をなくす"というのがいいなと思った。
  • v1.21の新しい機能ではpgoが良さそう
    • 弊社だとdev環境で負荷試験を実施してリリースというパターンがあるので、その後に組み込めると良さそう