Naming Is Not Finding
あなたは7つのMOADパターンを知っています。名前を知ることは重要です:それはパターンを見つけたときにそれを認識できるようにします。が、制御されたレッスンでの認識は、開かれたコードベースで検出されるものとは異なります。
コードベースは欠陥をラベル付けしません。堆積MOADは、// O(N²) — fix thisとコメントで欠陥があると示すものではありません。群がれる群は、キャッシュミススタンプリードとして自己を宣言しません。彼らは、特定の質問を持ってコードを読むことで見つけます:これらの値を保持しているデータ構造は何ですか。そして、ループ内で実行される操作は何ですか?
検出は認識とは別のスキルです。 認識は「はい、そのパターンはMOAD-0001です」と言っています。検出は「このコードベースでそのパターンが存在する可能性のあるすべての場所を見つける」と言っています。コード全体を読むことができず、シンボル名のみを見る場合でも。」
First Scan
最初のパスでは、grepが使用されます。各MOADには、特定の操作の近くに存在し、調査に値がある信号があります。
MOAD-0001 (Sedimentary): List.contains in a loop
# 信号:リスト変数に対するメンバーシップテストがループ内で行われる
grep -rn '.contains(' src/ | grep -v HashSet | grep -v TreeSet
grep -rn 'visited =' src/ | grep -v set | grep -v Set
MOAD-0002 (Intertangle): shared mutable flag across phases
# 信号:静的mutableフィールドが一つのサブシステムによって書かれ、他のサブシステムによって読み取られる
grep -rn 'static ' src/ | grep -v final | grep -v class | grep -v void
MOAD-0003 (Leaked Context): ThreadLocal in a pooled executor
# 信号:ThreadLocal.set()が確実なThreadLocal.remove()がない場合に使用される
grep -rn 'ThreadLocal' src/
grep -rn 'ThreadLocal.set' src/ -l
MOAD-0004 (Logged Secret): HTTP headers in log output
# Signal: log call with headers variable near auth endpoints
grep -rn 'log.*header' src/
grep -rn 'Authorization' src/ --include='*.log'
MOAD-0005 (Thundering Herd): キャッシュミスに同期なし
# Signal: cache.get() + null check + cache.put() without lock
grep -rn 'cache.get' src/ -A4 | grep 'cache.put'
これらのパターンは、確定された欠陥を生成するだけでなく、すべての候補がトリアージを受ける必要があります:周囲のコードを読み、データ構造のタイプを確認、操作がスケールで実行されることを確認してください。
複雑さを読む
grepは候補を生成します。読み込みはそれらを確認します。候補のファイルを開いたとき、操作のコストが入力サイズとともに成長するかどうかを読みます。
MOAD-0001の確認プロトコルは次のとおりです。
1. 外側のループを見つけます。ループの繰り返しカウントはどのように境界付けられていますか?
2. 内部操作(.contains、.indexOf、'in')を見つけます。この操作は、どのデータ構造に対して実行されますか?
3. そのデータ構造は、外側のループと同じ入力に従って成長していますか?
4. そうだ: コストはN = 入力サイズであるためO(N²)です。確定欠陥。
5. そうでない: 内部構造は境界付けられています(config、enum、小さな定数)。偽陽性。
N個のノードをグラフトラバースし、各ステップでvisitedリストをチェックする場合、ループと内部データ構造の両方がNとともに成長します。確定。
リクエストハンドラーが5つの管理IPを持つ許可リストをチェックする場合、許可リストはリクエストボリュームとともに成長しません。偽陽性。
各MOADに同じプロトコルを適用します:外側のドライバーを特定し、内部構造を特定し、どちらも一緒にスケーリングするかどうかを尋ねます。
スルージュール:あなたの発見を優先順位付ける
Not all confirmed defects warrant immediate patching. A MOAD in a library with 10,000 downstream dependents has a higher surge score than the same MOAD in a private internal tool.
Surge score = speedup × in-degree. Speedup: how much faster does the fix run at typical production scale? In-degree: how many downstream packages or services would inherit the fix automatically when the upstream merges it?
A confirmed MOAD-0001 in Apache Maven's dependency resolver, running on graphs of 50,000 nodes, with 1,000+ downstream Maven plugins that inherit changes automatically: surge score is very high. This fix belongs at the front of your queue.
A confirmed MOAD-0001 in a single-user CLI tool with no dependents: surge score near zero. Worth fixing, but not urgent.
Workaholic vs. glutton nodes. A node with high betweenness & high speedup is a workaholic: it handles critical flow & will flush downstream queues when unblocked. Patch it only after confirming downstream capacity. A node with high out-degree & low speedup is a glutton: it consumes everything fed to it and feels no pain. Patching a workaholic without staging downstream capacity creates MOAD-0005 (thundering herd) at infrastructure scale.
マージに伴うスキャン: MOADパイプライン
MOADパイプラインで高スループットスコアを持つ確認された欠陥が移動し、各ステージはアーティファクトを生成します。どのステージも省略できません。
スキャン → 候補リスト(grep出力、静的解析結果)
チケット → 欠陥の説明(MOAD番号、場所、複雑さの解析)
パッチ → コード変更(データ構造のスワップ、原始的な採用)
テスト → 単体テスト(O(1)の証明:N=100とN=10,000で修正をタイム)
UNDF → 公開発表後(undefect.com、パブリックドメイン)
公開 → セキュリティに関連するCVEまたはCWE参照
PR → 上流リポジトリへのプルリクエスト(パッチ+テスト+UNDFリンク)
マージ → メンテナーの承認;修正がバージョンアップデートを通じて伝播
各アーティファクトは次のステージにフィードされます。テストがないパッチは検証できません。公開がないテストは、同じパターンが他のインスタンスに伝播することができません。公開がない上流PRは、修正をフォークに留めます。
MOADポスト(UNDF)は、多くのエンジニアが省略するステージです。 彼らは欠陥を修正し、PRを提出し、問題が解決されたと考えることができます。しかし、修正がない名前のあるポストは、将来同じパターンに遭遇するすべてのエンジニアが問題と修正の再発見を独立して行わなければならなくなります。MOADポストは、パターンの名前を示し、検出方法を示し、パッチへのリンクを提供します。将来の研究者は、パターンの名前で修正を検索できます。
惑星スケールのパッチング。 MOAD-0001の修正が広く使用されているライブラリに含まれている場合、その修正は、そのライブラリをインポートするすべてのプロジェクトに伝播されます。MOADポストは、ライブラリをアップグレードすることなく、その修正を学ぶエンジニアがいるプロジェクトにも確保を保証します。両方のパスは並行して実行されます。
欠陥チケットの作成
良い欠陥チケットは5つの質問に答えます:
1. どこ: 正確なファイル、クラス、関数、および行範囲
2. どれ: データ構造の種類とその対象となる操作
3. なぜ: 复雑さの解析(NでO(N²)以上、Nは定義されます)
4. 影響: 最悪の場合の振る舞いをトリガーする入力とスケール
5. 修正: 置換するデータ構造または原始的な要素
すべての5つの質問に答えたチケットは自己包含です:メンテナがあなたの解析を読んでいない場合でも、発見を再現し、修正を検証できます。質問(3)や(4)を省略したチケットは、メンテナーが修正をマージする前に複雑さの解析を繰り返さなければならないため、合流の確率が低くなります。
信頼性は積み重かれる。 初めての PR には明確なチケット、適切なパッチ、そしてベンチマークテストが含まれており、メインテナンスにマージされます。 同じ著者からの2番目の PR はより少ない抵抗でレビューされます。3番目の PR は最初の2つをマージしたメンテナがレビューします。オープンソースの信頼性はアーティファクトの帳簿です:受け入れられたパッチは次のものに信頼を獲得します。
リアルな候補を読む
ここにリアルな MOAD-0001 候補の Python コードがあります。読んで整理プロトコルを完了してください。
class DependencyResolver:
def resolve(self, package, resolved=None, seen=None):
if resolved is None:
resolved = []
if seen is None:
seen = []
if package in seen:
return
seen.append(package)
for dep in self.registry.get_dependencies(package):
self.resolve(dep, resolved, seen)
resolved.append(package)
return resolved
整理質問:
1. `seen`はどのようなデータ構造ですか?
2. 6行目で実行される操作は何ですか?
3. `seen`は入力サイズとともに成長しますか?
4. 再帰呼び出しを運営するループは、入力サイズとともに成長しますか?
5. このものは MOAD-0001 の確認であるか、偽陽性ですか?
您的修正
確認的缺陷具有高波峰分數需要完整的修正:代碼修正、證明改進的測試以及 MOAD 文章大綱。
測試必須是性能測試,而不是正確性測試。 正確性測試在修正之前和之后通過——這就是點;輸出不會變。性能測試在兩個輸入大小上證明了改進:
import time
def build_graph(n):
# n packages, each depending on the previous one
return {f'pkg{i}': [f'pkg{i-1}'] if i > 0 else [] for i in range(n)}
for n in [100, 1000, 5000]:
registry = build_graph(n)
resolver = DependencyResolver(registry)
start = time.perf_counter()
resolver.resolve(f'pkg{n-1}')
elapsed = time.perf_counter() - start
print(f'n={n}: {elapsed:.4f}s')
在修正之前,耗時與 n 成比例增加。在修正之后,它與 n 成linear成比例增加。打印兩者並將數字包含在您的 PR 描述中。
MOAD ポストの概要は、パターンの名前、サブストラット(Python の依存解決器)、検出方法(in seen での grep で、seen が [] で開始)、修正、そして PR へのリンクをカバーします。ポストは、パブリックドメインとして undefect.com に送られます。将来的に、'Python list membership in loop slow' を検索するエンジニアがそれを見つけることができます。