Intellij IDEA で効率的にコーディングするためにやっていること

まとめ

Shift を2回押してどこでも検索を使おう。

まえがき

一般的に効率的にコーディングするためにはキーボードショートカット (以下、ショートカット) を使い、キーボードから極力手を離さないという方法があります。

しかし Intellij の場合、たくさんあるショートカットを覚えるのは大変ですし、操作によってはショートカットの割当設定が必要になるかもしれません。

また、Key Promoter X などのショートカットを教えてくれるプラグインがありますが、通知がたくさん出るのが私には合いませんでした。

どこでも検索

そこで私が使っているのがどこでも検索という機能です。

pleiades.io

機能の詳細は Intellij のドキュメントに任せますが、これによりショートカットを1つ1つ覚えたり設定する必要はなくなります。加えてショートカットを教えてくれるので、私はよく使う操作のショートカットを覚えることができました。

使い方

Shift + Shift (Shift キーを2回) で呼び出すことができます。

以下に2つ使用例を載せました。

例1: Git のブランチ切り替え

よく行う操作に Git のブランチ切り替えがあります。これをどこでも検索でやります。

まず、どこでも検索の検索ウィンドウを開き、「git branch」で検索したのが次の画像です。

Branches... の横に書かれている Ctrl+Shift+` は割り当てられているショートカットです。何度も実行しているうちに目に入って覚えられると思います。

「git branch」で検索

実行するとブランチを管理するウィンドウが開きます。

ブランチ操作のウィンドウ

例2: タブを全て閉じる

次は現在開いているタブをすべて閉じます。

どこでも検索で「close」と入力すると候補に Close All Tabs が出てきました。これを実行するとタブを全て閉じることができます。

「close」で検索

この操作にはショートカットがデフォルトで割り当てられていません。もちろん自分で割当設定をしてもいいのですが、設定が面倒であればこのように実行できます。

おわり

いちいち検索するのが面倒という意見がありそうですが、個人的には Emacs で関数を実行する感覚で使っていて気になりません。

GitHubのREST APIを使って名前に '/' の入ったEnvironmentを作る

要点: %2F/エスケープしてあげればいい

Create or update an environment

GitHub は Environment を作成する REST API を提供しています。

docs.github.com

使い方はリファレンスに詳しく書いてありますが、curl なら次のような感じ。適切な権限を付与したアクセストークン (GITHUB_PAT) を用いて、リポジトリ (OWNER/REPO) に ENVIRONMENT_NAME という名前で Environment を作るコマンドです。

export GITHUB_PAT=<YOUR_TOKEN>
export OWNER=<YOUR_OWNER>
export REPO=<YOUR_REPO>
export ENVIRONMENT_NAME=<YOUR_ENVIRONMENT_NAME>

curl -L \
  -X PUT \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer "${GITHUB_PAT}"" \
  -H "X-GitHub-Api-Version: 2022-11-28" \
  https://api.github.com/repos/"${OWNER}"/"${REPO}"/environments/"${ENVIRONMENT_NAME}"

トークンの作り方:

docs.github.com

Environment 名に '/' を使いたいとき

Environment 名に / を使って、例えば、production/backend というように構造化したいかもしれません。

その場合は、/%2Fパーセントエンコーディングする必要があります。

コマンド例 (ENVIRONMENT_NAME に注目):

export GITHUB_PAT=<YOUR_TOKEN>
export OWNER=<YOUR_OWNER>
export REPO=<YOUR_REPO>
# / を %2F に変換
export ENVIRONMENT_NAME=production%2Fbackend

curl -L \
  -X PUT \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer "${GITHUB_PAT}"" \
  -H "X-GitHub-Api-Version: 2022-11-28" \
  https://api.github.com/repos/"${OWNER}"/"${REPO}"/environments/"${ENVIRONMENT_NAME}"

エンコードしないとエラーレスポンスが返ってきます。

プライベートリポジトリだと具体的なエラーメッセージは無く、Not Found とだけ返ってくるので注意です。

{
  "message": "Not Found",
  "documentation_url": "https://docs.github.com/rest"
}

docs.github.com

補足1. ラベルの場合

Environment と同じように、Issue や Pull Request に付けるラベルも REST API を通じて作れます。

しかし、ラベルの場合は / が名前に入っていてもエスケープ処理が不要でした。

docs.github.com

補足2. プラン

GitHub Free プランでは、プライベートリポジトリで Environment を使えません。実際に試すときはリポジトリの可視性やプランを確認してください。

docs.github.com

2023年の振り返り

とりあえず書いた。

仕事

学生生活が終わり社会人になった。

chaya2z.hatenablog.jp

AWS でインフラ構築するのが主な仕事で、Terraform で IaC したり、TypeScript でツール書いたりしている。

よかった技術書

システム設計の面接試験

本のタイトルには「面接試験」とあるけれど普段の業務でも役立つ。内容がわかりやすいのはもちろん、参考文献がたくさん載っているのがよかった。

www.socym.co.jp

入門モダン Linux

短くまとまっているのと、図がわかりやすいのがよかった。

www.oreilly.co.jp

ロードバイクを買った

リモートワークで家に籠りがちなので運動のためロードバイクを買った。週末に80kmくらい乗ってる。

運動ならロードバイクである必要はないけれど、ずっとやりたいと思っていたので買った。やりたいと思っていたことが叶ったのは喜ばしいことなのだけど、このままやらなかったら一生やらずに死ぬんだろうと後ろ向きな感覚が芽生えてしまった。悲しい。

今は25km/hで数kmのペースなので、来年は30km/hで100km走れるようになりたい。.

来年

来年はもっとブログ書いたりコード書いたりアウトプットしたい。

来年もよろしくおねがいします。

Linuxカーネルの赤黒木のおもしろい最適化

この記事ははてなエンジニア Advent Calendar 2023 の27日目の記事です。はてなアドベントカレンダーはまだまだ続きます!

26日目の記事は id:masayosu さんの EKS Pod Identity を活用するメリットでした。

赤黒木とは

赤黒木は平衡二分探索木の1種で、各ノードが赤か黒の色に塗り分けられていることが特徴の1つです。

(Wikipedia の赤黒木のページの画像)

この記事では赤黒木に詳しい必要はないので、説明は wikipedia の赤黒木のページに任せます。

Linux カーネルでは、CFS スケジューラで用いられたりしています。

Linux の赤黒木のノード

Linux カーネルの赤黒木の実装を見ていきます。この記事では特に赤黒木のノードに注目します。

include/linux/rbtree_types.h (v6.6) にある rb_node が赤黒木のノードを表す構造体です。

struct rb_node {
    unsigned long  __rb_parent_color;
    struct rb_node *rb_right;
    struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));
/* The alignment might seem pointless, but allegedly CRIS needs it */

まず、rb_node 構造体は3つのフィールドを持っています。

  1. __rb_parent_color
    • 木の親と自身の色 (赤か黒) の情報
    • 下記で詳しく見ていきます。
  2. *rb_right
    • 右側の子ノードへのポインタ
  3. *rb_left
    • 右側の子ノードへのポインタ

次に、 __attribute__((aligned(sizeof(long)))) という部分はコンパイラにアライメント境界を伝えるキーワードです。

下記で詳しく見ていきます。

コミットログを追う

コミットログを読んで rb_node 構造体の理解を深めます。

v6.6 では rb_node 構造体は include/linux/rbtree_types.h に定義されていますが、v5.15 まで include/linux/rbtree.h ファイルに定義されていました1

なので、include/linux/rbtree.h の Git のコミットログを追います。

v2.6.12-rc2

Linux カーネルソースコードが Git で管理されるのは v2.6.12-rc2 からです。

そこで v2.6.12-rc2 から見ていきます。

include/linux/rbtree.h (v2.6.12-rc2)

struct rb_node
{
    struct rb_node *rb_parent;
    int rb_color;
#define    RB_RED      0
#define    RB_BLACK    1
    struct rb_node *rb_right;
    struct rb_node *rb_left;
};

v6.6 と大きく異なるのは、v2.6.12-rc2 の時点では __rb_parent_color フィールドは存在せず、 *rb_parentrb_color にフィールドが別れている点です。

v2.6.18

v2.6.18 で v6.6 とほとんど同じコードになります。

include/linux/rbtree.h (v2.6.18)

struct rb_node
{
    unsigned long  rb_parent_color;
#define    RB_RED      0
#define    RB_BLACK    1
    struct rb_node *rb_right;
    struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));
    /* The alignment might seem pointless, but allegedly CRIS needs it */

赤黒木に関するコミットはいくつかありますが、その中でも2つのコミットを見てみます。

[RBTREE] Merge colour and parent fields of struct rb_node.

We only used a single bit for colour information, so having a whole machine word of space allocated for it was a bit wasteful. Instead, store it in the lowest bit of the 'parent' pointer, since that was always going to be aligned anyway.

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v2.6.18&id=55a981027fc393c86de2c4e7836c9515088a9a58

このコミットで *rb_parentrb_colorrb_parent_colour というフィールドにまとまります。

struct rb_node
 {
-   struct rb_node *rb_parent;
-   int rb_color;
+   unsigned long  rb_parent_colour;
 #define   RB_RED      0
 #define   RB_BLACK    1
    struct rb_node *rb_right;
    struct rb_node *rb_left;
 };

親へのポインタ ( *rb_parent ) の最下位1ビット (LSB) に色情報 ( rb_color ) を格納することでメモリの無駄遣いを防ぐことができるということがコミットメッセージに書いてあります。

なぜ、ポインタの LSB に色情報を格納できるのでしょうか。

それは、親へのポインタは偶数アドレスに配置されるので、LSB は必ず0になるからです。ポインタが偶数アドレスになる理由は、rb_node 構造体がアライメントされてメモリに配置されるからです。

このようなポインタの使い方を Tagged pointer と呼ぶらしいです。

ちなみに、colour というのは typo ではなくイギリス英語のスペルです。v2.6.18 のリリースまでにアメリカ英語の color に変更されました2

[RBTREE] Add explicit alignment to sizeof(long) for struct rb_node.

Seems like a strange requirement, but allegedly it was necessary for struct address_space on CRIS, because it otherwise ended up being only byte-aligned. It's harmless enough, and easier to just do it than to prove it isn't necessary... although I really ought to dig out my etrax board and test it some time.

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v2.6.18&id=e977145aeaad23d443686f2a2d5b32800d1607c5

__attribute__ というコンパイラにアライメント境界を伝えるキーワードが追加されます。

+} __attribute__((aligned(sizeof(long))));
+    /* The alignment might seem pointless, but allegedly CRIS needs it */

通常、コンパイラはこのコードが無くてもアライメントするはずですが、 CRIS ではそれがうまくいかないらしいということがコミットメッセージでわかります。

__attribute__GCC の構文3で、構造体と共用体に属性を付与できます。aligned は属性の1つで、アラインメントの境界を指定できます。64ビットアーキテクチャでは long 型は8バイトなので、8バイトアライメントされるはずです。

CRIS というのは Axis Communications 社の開発しているアーキテクチャのことだと思います4

まとめ

Linux カーネルの赤黒木の実装に見る Tagged Pointer を用いた最適化の話でした。


この記事ははてなエンジニア Advent Calendar 2023 の27日目の記事でした。

明日の記事は id:SlashNephy さんです。

参考

Jetbrains AI Assistant を使ってみた

2023年12月6日、ついに Jetbrains AI の提供が始まりました。

blog.jetbrains.com

この AI 機能は、2023年7月ごろにテクニカルプレビューとして登場しました。私もそれを試用して、その機能に魅力を感じていました。そのため今回リリースされてすぐにライセンスを購入し、さっそく利用してみました。

この記事では、個人的に特に魅力を感じた Explain Code 機能を紹介します。

Explain Code 機能がすごい

AI チャットの機能の1つに Explain Code という機能があります。これはその名の通り、コードの意味を説明してくれるものです。

例えば、 Linux カーネルの CPU スケジューラの初期化関数を解説してもらうとこんな感じです。

コード: https://elixir.bootlin.com/linux/latest/source/kernel/sched/core.c#L9912

AIにコードを解説してもらう

まず、1行目で、「これは Linux カーネルのコードでタスクスケジューラの初期化部分です」と説明されます。

This is a part of the Linux kernel code which is responsible for initializing the task scheduler.

こちらからこの関数が Linux カーネルのコードの一部であることは伝えていないので、AI がコードを見て推測しているということでしょう。

次に、 __initLinux カーネル独自のものであることを教えてくれます。

This function is named sched_init and is tagged with __init which in Linux kernel programming means that this function is executed only once at startup and its memory can be freed up after this.

もう少し説明がほしいと思ったので、AI Assistant に聞いてみました。

AI Assitant に質問する

先程より詳しい解説が返ってきました。

要約すると、「これは Linux カーネルのマクロで、カーネルがメモリにロードされるときに1度呼び出され、メモリを効率的に扱えるようにするものです」と答えてくれています。

感想

まだすべての機能を試していませんが、AI チャットだけを見ても Jetbrains AI に期待できるのではないでしょうか。

関連

www.jetbrains.com

www.youtube.com

Intellij IDEAでemoji入力 (プラグイン不要)

Intellij IDEA など、Jetbrains 社の IDE で emoji (絵文字) を入力する方法を知ったのでメモ。

TL;DR

Ctrl+Alt+;

概要

IntelliJ IDEA 2020.3 でリリースされた機能の1つです。

www.jetbrains.com

What’s New ページより - Linux emoji picker

Linux emoji picker という見出しで紹介されています。

for Linux と書かれているので、このアップデートは Linux ユーザ向けということだと思います。Windowsmac ではどうなっているのかわかりません。

使ってみる

デフォルトでは、 Ctrl+Alt+; で emoji picker を開けます。

emoji picker

もし emoji picker が開かない場合、Ctrl+Alt+;Emoji & Symbols に割り当てられているか確認してください。

keymap の設定