優れた技術専門職になるためのガイド」の内容レビューに関わらせていただきました。書籍をご恵贈いただきました。島田浩二さんの記事をお見かけして、手を挙げさせていただきました。https://snoozer05.hatenablog.jp/entry/2024/02/17/083955島田さんによる書籍の紹介記事を是非ご覧ください。snoozer05.hatenablog.jp翻訳している中で、仕事で技術リーダーとして開発に携わる中で、技術的な面や組織的な面で参考にさせていただく点が非常に多くあり、翻訳のレビューをするうえで何度もうなづきながら読み進め、私自身大変多くの学びを得ることができました。今後もエンジニアとして仕事をする上で何度も読み直すことになるような本だと考えており、このような本の制作に関わることができて大変光栄です。私自身将来的に技術書の執筆に携わりたいと思っていたところで、翻訳レビューの機会をいただきました。様とオライリー・ジャパン様には、このような貴重な機会をいただき、大変感謝しております。将来的に組織で技術で貢献したい方、すでに何らかの技術的なリーダーシップを発揮している方には本当に参考となる書籍ですので、ぜひ手に取ってみてください。setする際に、キーがまだ存在していない場合にのみ値をセットできるもので、redisによるロック処理に使われます。このnxオプションについて調べてみます。簡単なロック機能を試してみます。いうコマンドを実行します。コマンド実行時に既にキーが存在していない場合のみsetできる。10秒間のTTLを設定する。キーを登録してから10秒を超えるとキーに紐づくデータが消える上記のコマンドにより、10秒間のロック機能を実現します。同じコマンドを実行してロックを獲得しようと試みても失敗することを確認できました。NXとEXオプションをつけることで簡単なロック機構を実現できます。nxオプションが付いていた場合の内部実装についてnxオプションをつけた時にsetコマンドではどういう処理になっているかを説明します。関数から辿ることができます。GitHubset実行時のNXオプションがついているかの判定set実行時のオプション引数のパース処理をみてみます。関数で実装されています。立てる処理を行っています。続いて、NX用のフラグが立っている場合にsetコマンドでどういう処理が行われるかをみてみます。関数で実装されています。関数の前半の方で、まず指定したキーがデータに存在しているかを確認し、存在していた場合はアーリーリターンして、コマンドの実行を終了し、その後にデータを登録する処理はスキップされます。setでnxオプションをつけて実行された場合はデータの登録はされずにスキップされることになります。この後、setの処理が続く...以上となります。EXまたはPXオプションを設定した場合、指定した時間が経ったらキーの値が削除され、ロックが解除されることになります。その後再度ロックをかけることができます。rangeでmapをループさせる際のイテレーション順序について整理します。rangeでmapの要素をループさせる際、イテレーションの順序は決まっていません。これはGo言語の仕様で定められており、ループ順序を前提としたコードを書かないために定められています。order.go.devこの順序が実際にどう決まっているかについて、Goのランタイムでどういう実装になっているかを整理します。rangeによってループさせる例を示します。}}mapの要素をイテレートして、そのキーと値を表示させます。これを実行すると、実行するごとに要素の順番が変わっていることを確認できます。mapのイテレーションで順序が保証されていない理由この理由については、簡単にいうとGoの古いバージョンからの互換性を保つためのものとなります。古いバージョンでは、もともとmapのイテレーション順について仕様で定義されていませんでした。そのため実行するハードウェアプラットフォームによって異なっていたようです。これにより、mapをイテレーションするテストでは実行する環境でテスト結果が異なってしまい、環境によってテストが成功したりしなかったりするという課題がありました。rangeによるmapのイテレーション順は不定であると定義されました。rangeを扱っている箇所は修正が必要です。mapのイテレーション時の処理について次に、実際にGoランタイムではmapのイテレーションの順番をどのように決めているかについて整理します。mapのデータ構造についてGoにおけるmapのデータ構造について説明します。Goにおいては、mapはハッシュテーブルと同義です。map内にバケットが存在し、そのデータはバケットの配列に格納されます。各バケットは最大8つのキー・バリューのペアを含むことができます。そのハッシュ値の下位のビットは、どのバケットを選択するかを決めるのに利用されます。上位のビットは単一のバケット内のどのエントリかを決めるのに利用されます。あるバケットで8より多い数のデータが追加された場合、追加のバケットを連結し、そこに格納されます。ハッシュテーブルを増やす必要がある際、Goランタイムはその時点でのバケット数を2倍にし、新しい配列を持ったバケットを追加します。いう構造体も用意されています。イテレーションの開始するバケットを選択するものになります。イテレーションの初期化処理において、この値を設定する箇所があります。いう関数で実装されています。GitHubこの初期化処理の中で、map内のどのバケットから処理をするかを決めていますが、この際に乱数をもとにバケットを選択しています。mapのイテレーションの順番が不定となるのは、この処理によるものであることがわかります。おわりに以上となります。mapについての概要の説明を行いました。rangeにおけるmapのイテレーションの順序は仕様で不定となっていて、Goランタイムの実装を確認し、実際にイテレーションの初期化処理で開始位置がランダムになっていることを確認できました。今回は取り上げませんでしたが、Goランタイムの実装は非常に興味深いため、別の記事でも気になる箇所について取り上ようと思います。概要Goのコンパイラにおいて、コンパイル時にいくつかのフェーズに分かれており、各フェーズについてざっと概要を整理します。github.comGoコンパイラによるコンパイルでは、主に下記のようなフェーズをたどります。マシンコードの生成Goコンパイルのフェーズ字句解析と構文解析cmd/compile/internal/syntaxgithub.comコンパイルの最初のフェーズでは、ソースコードはトークナイズ(字句解析)とパース(構文解析)され、それぞれのソースファイルに対してシンタックスツリーが構成されます。各シンタックスツリーはそれぞれのソースファイルを正確に表現したもので、ノードはソースのさまざまな表現(式・宣言・文など)に対応しています。シンタックスツリーには位置情報も含まれており、エラーリポートやデバッグ情報の生成に使用されます。パッケージはgo/typesをgo/astの代わりに構文パッケージのASTを使用するように移植したものです。AST)ここでは、構文解析と型チェックの結果を、コンパイラが理解できる中間表現(IR)に変換するプロセスを扱います。自身のAST定義とCで書かれた時代から引き継いだGoの型の表現を使います。中間表現と型に変換します。IRと呼ばれるプロセスを用います。これはステップ2で型チェックが完了したコードをシリアライズしたものを利用して、Nodeを構成します。IRはパッケージのimport/exportやインライニングに関わります。analysis)中間表現に対して、いくつかの最適化プロセスが実施されます。呼ばれ、2つの目的があります複雑な文を個々のより単純な文に分解し、一時変数を導入し、評価の順序を尊重します。