メインコンテンツまでスキップ

Software Design 202404

Linux 基礎

ディレクトリ構成とファイルシステム

  • Windows と Linux のディレクトリーツリーの違い
    • Windows: ストレージ内のパーティションがドライブ(C:、D:)となり、それぞれが独立したディレクトリーツリーを持つ
    • Linux: システム全体で単一のディレクトーツリーを持つ。言い換えると、ルートディレクトリ(/)以下に他のドライブを含めた全てのディレクトリが配置される。
  • ハードリンク
    • inode 番号を使って紐付ける
    • ln -i で inode 番号を確認できる
    • ln file1 file2 でハードリンクを作成できる
  • シンボリックリンク
    • 異なるファイルシステム間でもリンクが可能
    • パス名を使って紐付ける
    • ln -l でシンボリックリンクを確認できる
    • ln -s file1 file2 でシンボリックリンクを作成できる
    • リンク先のファイル名を変更するとリンクが切れる

プロセス管理

  • プロセスとは
    • 実行中のプログラムに関する情報を OS が管理するための構造体
  • プロセス ID
    • psで確認できる
    • $$ で現在のシェルのプロセス ID を取得できる
  • プロセスの状態
    • R (Running または Runnable): CPU を使っているまたは使いたい状態
    • S (Interruptible Sleep): 中断できるスリープ
    • D (Uninterruptible Sleep): 中断できないスリープ。ディスク I/O 待ちなど。
    • T (Stopped): シグナルによって停止された状態
    • Z (Zombie): 親プロセスに終了ステータスを通知できずに悪霊になった状態 / defunct とも呼ばれる
    • ...ほか多数
  • プロセスの親子関係
    • pstree $PID で確認できる
  • init プロセス
    • 全てのプロセスの祖先
    • init プロセスが他のプロセスを起動することで、Web サーバが動いたり ssh で接続できるようになったりする
  • プロセスが終了するとどうなるか
    • プロセスが終了すると、親プロセスに終了ステータスが返される
    • 親プロセスは終了ステータスを$?変数に入れる
  • 親プロセスが先に死ぬとどうなるか
    • 子プロセスの親プロセスが init プロセスに付け替えられる
  • ゾンビプロセス
    • プロセスが終了したが、親プロセスが終了ステータスを取得していない状態
  • プロセスの情報取得
    • 歴史的経緯により混沌としているので都度調べるで OK
    • ps aux
    • ps o pid,ppid,comm,stat

ユーザー権限とアクセス権

  • ユーザー ID / ユーザー名
    • ユーザー名は人間が扱いやすいが、システムはユーザー ID を扱う
    • ls -n とすると所有ユーザー ID を確認できる
  • root
    • システムを管理するための特権ユーザー
    • ユーザー ID は 0
    • 最近は root ユーザーでの作業は推奨されず、代わりにsudoが使われる
  • システムユーザー
    • 特定のサービスを実行するためのユーザー
    • 例えば SMTP サーバや HTTP サーバなどのプロセスは、システムユーザーで実行される
    • ユーザー ID が 1 から 999
  • 一般ユーザー
    • ID は 1000 以上
  • su
    • 別のユーザーに切り替えるコマンド
    • 引数なしで実行すると root に切り替わる
    • --login オプションをつけるとログインシェルとして利用できる。そのユーザーの環境変数などを完全に引き継ぎたい時に使う。
  • sudo
    • 別のユーザーとしてコマンドを実行するためのコマンド
    • sudo -u USERNAMEのように使う。-uを省略すると root になる
    • /etc/sudoersファイルに設定が書かれている。編集時にはvisudoを使え。
    • 複数コマンドを実行したいときはsudo sh -c "command1; command2"のようにする。そうしないと2番目が一般ユーザーで実行されてしまう。
  • runuser
    • システム管理者が他のユーザーとしてコマンドを実行するために使用する
    • 環境変数を維持する点で su コマンドに似ている
    • su のようにパスワードや tty を要求することはないため、主にスクリプト内での利用に重宝する

テクニカルライティング

読み手に合わせて文章を書こう

まずは読み手の前提知識がどの程度あるかを把握する。エキスパート向けなのか初心者向けなのかなど。

つぎに読み手の目的を把握すること。読み手が何を知りたいのか、どのくらい詳細に求めているのかなど。

そのうえで、以下のような工夫をすると良い。

  • 用語を適切に選択する
    • 専門用語を使うか使わないかなど
  • 書くべき情報を絞ったり、ドキュメントを分解したりする
    • 読み手の前提知識や目的に合わせて、必要な場所だけ読めるようにする
  • 読み手の範囲を絞り込む
    • 範囲を絞ればコスパは上がる
    • 冒頭に「対象読者、説明すること、説明しないこと」を明記するとよい

アウトラインで伝える情報を整理しよう

アウトラインを作成する際は以下の手順で行う。

  • 伝えたい情報を書き出す
  • 書き出した情報を階層化する
  • 項目を並べ替える
    • 「重要度」or「ニーズの大きさ」の順に並べ、次に「既知から未知」or「時系列」で並べるとよい。
  • 見出しにする要素を選ぶ
    • すべてを見出しにする必要はなく、小さなものは段落ですませてもよい
  • 見出しに分かりやすい名前を付ける

明確な文章を書こう

効率良く読める文章を書くために

ドキュメントは飛ばし読みされるものと心得よ。例えば F パターンなど。

重要なことから書こう。重要とは、読み手に必ずやってほしいことや、書き手の主張である。

一文一義で書こう。長い文章は読みづらい。1 つの行動ごとに 1 つの文章にするとよい。

一文を短くしよう。余分な接続詞を削ったり、「まずはじめに」を「まず」にするなど。

読み手の視点の言葉で書こう。このとき、能動態(読み手の行動)と受動態(行動の結果)を適切に使い分けよう。例えば「PR の作成をトリガーとしてテストを実行します」ではなく「PR を作成するとテストが実行されます」のように。

主語と述語を対応させよう。主語と述語以外の部分を省いても意味が通じるかどうかを確認するとよい。

係り受けを明確にしよう。主語と述語を近づけたり、複数の修飾語がある場合は長いほうを前に持ってきたりすると改善する。

並列(not 順列)の情報が3つ以上ある場合には箇条書きにしよう。

読点を適切に打とう。意味の切れ目や誤解されそうなところに打つとよい。

誤解を招かない文章を書くために

できるだけ具体的に書こう。例えば「すぐに」という表現は曖昧なので、具体的な時間を書くなど。

肯定形で書こう。「残したままにしないでください」ではなく「消してください」とするなど。なお、否定形は禁止事項を伝える際に使うとよい。

二重否定を避けよう。それ、肯定形で書けますから。

「の」は一文に2つまで。それ以上になったら言い換えられないか考えよう。

段落の作り方

段落とは、同じ内容のまとまりごとに分けた一区切りのこと(日本人が小学校で習う段落は改行とイコールだが、ここで言う段落はそれとは異なる)。

段落を作るときは、はじめにトピックセンテンスを書く。これは段落の要約である。

つぎにサポートセンテンスを書く。これはトピックセンテンスを補足する内容、具体例、理由や根拠などである。

その後、話題を展開していく。この際「概要から詳細へ」を意識する。並列の情報は同じ表現を使って書く。順列の情報は「既知から未知へ」の流れで書く。

リソースレコード変更時のベストプラクティス

リソースレコードの設定変更は即時に反映されない場合がある。このため、TTL をあらかじめ 300 秒くらいに短くしておくのがよい。ただし、後で戻すのを忘れずに。通常は 3,600 秒くらいがよい。

もしトラブルシュートが必要になったら、dig を使って非再帰問い合わせをしたり、キャッシュ問題の切り分けのために別のネットワークや端末から確認してみたりするのが有効である。

ネガティブキャッシュ問題

サブドメインを新たに設定する際などに、設定前に(まだ存在しない)サブドメインにアクセスしたときに上位の権威サーバがNODOMAINを返すことで、その情報が TTL 期間キャッシュされてしまい、その間はサブドメインにアクセスできなくなる問題。非常に厄介な問題だが、dig での非再帰問い合わせや、別のキャッシュサーバを使って状況を確認するのが有効。

権威サーバ引っ越し時のベストプラクティス

権威サーバ(ドメイン管理サイトで登録している NS レコードのこと)を引っ越す場合には、TTL が効かない。このため、数日間は新旧どちらの権威 DNS にもリクエストが飛ぶことになる。スムーズな移行のためには以下の手順を踏むことが大事。

  • 新旧権威サーバでリソースレコードをあらかじめ同期しておく
  • 権威サーバ(e.g. Napecheap のコンソールで登録している NS レコードの内容)を書き換えて数日待つ
  • その後、もし A レコードの変更などがあわせて必要であれば前述の手順に沿って行う

Chrome

画面を描写する仕組みは、Content、レンダリングエンジン(Blink 本体)、サードパーティライブラリ(V8, Skia ほか)の3層からなる。

Content が提供する Content public API によって Chrome その他の各種ブラウザから利用できるようになっている。

プロセスには以下のようなものがある。

  • ブラウザプロセス
    • Web サイトの描写エリアの外側に責務を負う
    • 戻るボタンやブックマークの機能など
    • プロセスは 1 つ
  • レンダープロセス
    • Web サイトの描写を行う
    • タブごとに 1 つずつのプロセス
  • Viz プロセス
    • 前述の2つのプロセスを組み合わせて実際に画面を描写する
    • プロセスは 1 つ

開発者体験

腐った iOS アプリを再建した手順を紹介。

まずは UI テストの実装。Firebase Test Lab 上で UI テストを実装した。画面操作を行った後に、正しいリクエストが送信されるか検証するもの。

次にリアーキテクチャ。TCA という Redux 的なものを導入して状態変化を追いやすくした。

他にも Renovate によるライブラリの自動更新や、VRT の導入などを行った。

データベースリファクタリング

「キャッシュ中毒」というアンチパターンがある。サービスが強くキャッシュに依存してしまい、非常に壊れやすくなり、運用が難しくなる状態のこと。一方で過度な忌避もよくない。適切なバランスを保つことが重要。

まずは RDBMS の性能を使い切るのが先。ほとんどの問題はこれで解消される。具体的には、インデックスの活用、クエリの最適化、テーブルの正規化など。

キャッシュに適しているものは以下のとおり。

  • アクセス数が多い
  • 計算コストが高い
  • 更新頻度が少ない

また、データ更新のアルゴリズム、生存期間のアルゴリズムには様々な種類があるので、最適なものを選択すること。

AWS Systems Manager

AWS Systems Manager は、サーバの管理を行うためのサービス。Lanscope Cat + α みたいなやつで、情報収集、リモート操作、パッチの適用、メンテナンス処理などを行うことができる。他クラウドやオンプレのサーバ、IoT デバイスにも対応している。