English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

visitante
1 / ?

Nomear Não é Encontrar

Você agora conhece sete padrões MOAD. Saber nomes é importante: permite reconhecer um padrão quando você o vê. Mas o reconhecimento em uma lição controlada é diferente da detecção em uma base de código que você nunca abriu.

Uma base de código não rotula seus defeitos. Um MOAD sedimentar não vem com um comentário que diz // O(N²) — corrigir isto. Um rebanho trovejante não se anuncia como um cache miss stampede. Você os encontra lendo código com uma pergunta específica em mente: que estrutura de dados mantém esses valores, & que operações executam contra ela dentro de um loop?

A detecção é uma habilidade separada do reconhecimento. O reconhecimento diz: sim, esse padrão é MOAD-0001. A detecção diz: deixe-me encontrar todos os lugares nesta base de código onde esse padrão pode existir, se eu posso ver o código completo ou apenas um nome de símbolo.

Seven MOADs: substrates, signatures, fixes

Primeira Varredura

Uma primeira passagem usa grep. Cada MOAD tem um substrato: uma estrutura de dados ou API cuja presença, perto de certas operações, é um sinal que vale a pena investigar.

MOAD-0001 (Sedimentário): List.contains em um loop

# Signal: membership test on a list variable inside 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): bandeira mutável compartilhada entre fases

# Signal: static mutable field written by one subsystem, read by another
grep -rn 'static ' src/ | grep -v final | grep -v class | grep -v void

MOAD-0003 (Leaked Context): ThreadLocal em um executor em pool

# Signal: ThreadLocal.set() without guaranteed ThreadLocal.remove()
grep -rn 'ThreadLocal' src/
grep -rn 'ThreadLocal.set' src/ -l

MOAD-0004 (Logged Secret): cabeçalhos HTTP na saída de log

# Signal: log call with headers variable near auth endpoints
grep -rn 'log.*header' src/
grep -rn 'Authorization' src/ --include='*.log'

MOAD-0005 (Thundering Herd): cache miss sem sincronização

# Signal: cache.get() + null check + cache.put() without lock
grep -rn 'cache.get' src/ -A4 | grep 'cache.put'

Esses padrões produzem candidatos, não defeitos confirmados. Cada candidato precisa de triagem: leia o código circundante, verifique o tipo de estrutura de dados, confirme que a operação é executada em escala.

Escolha um MOAD de MOAD-0001 até MOAD-0005. Descreva uma etapa concreta de detecção que você tomaria em uma base de código que nunca leu antes: o que você pesquisa, como é um resultado positivo & o que distingue um defeito confirmado de um falso positivo.

Lendo Código para Complexidade

Grep encontra candidatos. A leitura os confirma. Quando você abre um arquivo candidato, você lê com uma pergunta: o custo desta operação cresce com o tamanho da entrada?

Para MOAD-0001, o protocolo de confirmação:

1. Find the outer loop. What bounds its iteration count?
2. Find the inner operation (.contains, .indexOf, 'in'). What data structure does it run against?
3. Does that data structure grow with the same input that drives the outer loop?
4. If yes: the cost is O(N²) where N = input size. Confirmed defect.
5. If no: the inner structure is bounded (config, enum, small constant). False positive.

Um grafo que visita N nós, verificando uma lista visited em cada passo: tanto o loop quanto a estrutura de dados interna crescem com N. Confirmado.

Um manipulador de requisições verificando uma lista de permissões de 5 IPs de administrador: a lista de permissões nunca cresce com o volume de requisições. Falso positivo.

O mesmo protocolo se aplica a cada MOAD: identifique o driver externo, identifique a estrutura interna, pergunte-se se ambos escalam juntos.

Surge Score: Priorizando Suas Descobertas

Nem todos os defeitos confirmados garantem correção imediata. Um MOAD em uma biblioteca com 10.000 dependentes downstream tem uma pontuação de surge maior do que o mesmo MOAD em uma ferramenta interna privada.

Surge score = speedup × in-degree. Speedup: quanto mais rápido a correção é executada em escala típica de produção? In-degree: quantos pacotes ou serviços downstream herdariam a correção automaticamente quando o upstream os mesclar?

Um MOAD-0001 confirmado no dependency resolver do Apache Maven, executado em grafos de 50.000 nós, com 1.000+ plugins Maven downstream que herdam alterações automaticamente: surge score é muito alto. Esta correção pertence à frente de sua fila.

Um MOAD-0001 confirmado em uma ferramenta CLI de usuário único sem dependentes: surge score próximo a zero. Vale a pena corrigir, mas não urgente.

Workaholic vs. nós glutão. Um nó com alta betweenness & alta speedup é um workaholic: ele lida com fluxo crítico & varrará filas downstream quando desbloqueado. Corrija-o apenas depois de confirmar a capacidade downstream. Um nó com alta out-degree & baixa speedup é um glutão: consome tudo o que é alimentado & não sente dor. Corrigir um workaholic sem preparar capacidade downstream cria MOAD-0005 (thundering herd) em escala de infraestrutura.

Factory DAG: workaholic & glutton node patterns

Você confirmou MOAD-0001 em dois lugares: (A) um dependency resolver em uma ferramenta de compilação com 200.000 projetos ativos dependendo dela, executada em grafos de 10.000 nós de dependência; (B) um utilitário de grafo em um pipeline de dados interno de uma única empresa, executada em grafos de 50 nós. Compare suas surge scores. Qual você corrige primeiro, & que etapas você toma antes de divulgar?

Escanear para Mesclar: Um Pipeline MOAD

Um defeito confirmado com uma pontuação de surge alta passa por um pipeline. Cada etapa produz um artefato. Nenhuma etapa é opcional.

scan    → candidate list (grep output, static analysis results)
ticket  → defect description (MOAD number, location, complexity analysis)
patch   → code change (data structure swap, primitive adoption)
test    → unit test (O(1) proof: time the fix at N=100 and N=10,000)
UNDF    → public disclosure post (undefect.com, public domain)
disclose → CVE or CWE reference if security-relevant
PR      → upstream pull request with patch + test + UNDF link
merge   → maintainer acceptance; fix propagates via version bump

Cada artefato alimenta a próxima etapa. Um patch sem teste não pode ser verificado. Um teste sem divulgação não pode se propagar para outras instâncias do mesmo padrão. Uma divulgação sem um PR upstream prende a correção em um fork.

Um post MOAD (UNDF) é a etapa que a maioria dos engenheiros omite. Eles corrigem o defeito, enviam um PR, e se consideram prontos. Mas uma correção sem um post nomeado significa que todo engenheiro futuro que encontrar o mesmo padrão deve redescobrir tanto o problema quanto a correção independentemente. Um post MOAD fecha o loop do conhecimento: ele nomeia o padrão, mostra o método de detecção, & vincula ao patch. Pesquisadores futuros encontram a correção pesquisando o nome do padrão.

Planet patching em escala. Uma única correção MOAD-0001 em uma biblioteca amplamente usada se propaga para cada projeto que a importa. Um post MOAD garante que engenheiros em projetos que nunca atualizarão essa biblioteca ainda aprendam a correção. Ambos os caminhos funcionam em paralelo.

Escrevendo um Tíquete de Defeito

Um bom tíquete de defeito responde cinco perguntas:

1. Where: exact file, class, function, and line range
2. What: the data structure type and the operation against it
3. Why: the complexity analysis (O(N²) or worse, with N defined)
4. Impact: what inputs trigger worst-case behavior, and at what scale
5. Fix: the data structure or primitive to substitute

Um tíquete que responde aos cinco é independente: um mantenedor que nunca leu sua análise pode reproduzir sua descoberta & verificar sua correção. Tíquetes que pulam (3) ou (4) exigem que o mantenedor repita sua análise de complexidade antes de poder mesclar. Esse atrito reduz a probabilidade de mescla.

Credibilidade compõe. Um primeiro PR que inclui um tíquete claro, um patch bem direcionado, & um teste de benchmark é mesclado. Um segundo PR do mesmo autor é revisado com menos atrito. Um terceiro PR é revisado pelo mantenedor que mesclou os dois primeiros. A reputação no open source é um registro de artefatos: cada patch aceito ganha confiança para o próximo.

Escreva um tíquete de defeito mínimo para um MOAD-0001 que você esperaria encontrar em uma biblioteca de grafo. Inclua: (1) um nome de arquivo/função plausível, (2) a estrutura de dados & operação, (3) uma declaração de complexidade, (4) um cenário típico de impacto, (5) a correção.

Lendo um Candidato Real

Aqui está um candidato real de MOAD-0001 em Python. Leia-o e complete o protocolo de triagem.

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

Perguntas de triagem:

1. What data structure is `seen`?
2. What operation runs against it on line 6?
3. Does `seen` grow with input size?
4. Does the loop that drives recursive calls also grow with input size?
5. Is this a confirmed MOAD-0001 or a false positive?
Trabalhe através das cinco perguntas de triagem para este código. Depois escreva a correção de uma linha & explique por que isso não muda a saída da função.

Seu Patch

Um defeito confirmado com uma pontuação de surge alta precisa de um patch completo: a correção de código, um teste que prova a melhoria, & um esboço de post MOAD.

O teste deve ser um teste de performance, não um teste de correção. Um teste de correção passa antes & depois da correção — esse é o ponto; saída não muda. Um teste de performance em dois tamanhos de entrada prova a melhoria:

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')

Antes da correção, tempo decorrido cresce quadraticamente com n. Depois da correção, ele cresce linearmente. Imprima ambos & inclua os números na descrição do PR.

Um esboço de post MOAD cobre: o nome do padrão, o substrato (Python dependency resolver), o método de detecção (grep para in seen onde seen começa como []), a correção, & um link para seu PR. O post vai para undefect.com como domínio público. Engenheiros futuros pesquisando por 'Python list membership in loop slow' encontrarão.

Você confirmou & corrigiu MOAD-0001 em uma ferramenta de empacotamento Python popular. Antes de abrir o PR, que três coisas você inclui na descrição do PR, & por que cada uma importa para o mantenedor?