Construindo Swift em WSL2 (Linux)

O ecossistema Swift está se desenvolvendo ativamente fora das plataformas Apple e hoje é bastante confortável escrever nele no Windows usando o Windows Subsystem for Linux (WSL2). Vale a pena considerar que para assemblies no Linux/WSL, uma versão leve do Swift está disponível – sem estruturas proprietárias da Apple (como SwiftUI, UIKit, AppKit, CoreData, CoreML, ARKit, SpriteKit e outras bibliotecas específicas do iOS/macOS), mas para utilitários de console e backend isso é mais que suficiente. Neste post, vamos percorrer passo a passo o processo de preparação do ambiente e construção do compilador Swift a partir do código-fonte dentro do WSL2 (usando Ubuntu/Debian como exemplo).

Atualizamos a lista de pacotes e o próprio sistema:

sudo apt update && sudo apt upgrade -y

Instale as dependências necessárias para a compilação:

sudo apt install -y \
  git cmake ninja-build clang python3 python3-pip \
  libicu-dev libxml2-dev libcurl4-openssl-dev \
  libedit-dev libsqlite3-dev swig libncurses5-dev \
  pkg-config tzdata rsync

Instale o compilador e vinculador (LLVM e LLD):

sudo apt install -y llvm lld

Clone o repositório Swift com todas as dependências:

git clone https://github.com/apple/swift.git
cd swift
utils/update-checkout --clone

Instale o `swiftly` e o swift pronto com swiftc

curl -O https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz && \
tar zxf swiftly-$(uname -m).tar.gz && \
./swiftly init --quiet-shell-followup && \
. "${SWIFTLY_HOME_DIR:-$HOME/.local/share/swiftly}/env.sh" && \
hash -r

Vamos começar a construção (isso levará muito tempo):

utils/build-script \
  --release-debuginfo \
  --swift-darwin-supported-archs="x86_64" \
  --llvm-targets-to-build="X86" \
  --skip-build-benchmarks \
  --skip-test-cmark \
  --skip-test-swift \
  --skip-ios \
  --skip-tvos \
  --skip-watchos \
  --skip-build-libdispatch=false \
  --skip-build-cmark=false \
  --skip-build-foundation \
  --skip-build-lldb \
  --skip-build-xctest \
  --skip-test-swift

Após a conclusão da compilação, adicione o caminho do compilador ao PATH (especifique o caminho para a pasta de compilação):

export PATH=/root/Sources/3rdparty/build/Ninja-RelWithDebInfoAssert/swift-linux-x86_64/bin/swiftc:$PATH

Verificamos se a versão instalada do Swift está funcionando:

swift --version

Crie um arquivo de teste e execute-o:

echo "print(\"Hello, World!\")" > hello.swift
swift hello.swift

Você também pode compilar o binário e executá-lo:

swiftc hello.swift
./hello

Fontes

Teflecher

Teflecher é um aplicativo de teste rápido, interativo e multiplataforma desenvolvido com base no Kotlin Multiplatform (KMP) e no Compose Multiplatform. Ele permite que os usuários carreguem questionários intuitivamente de arquivos JSON locais ou URLs remotos, respondam a perguntas de múltipla escolha, vejam feedback instantâneo sobre as respostas corretas e rastreiem seus resultados.

Rede:
https://demensdeum.com/software/teflecher/

GitHub:
https://github.com/zefir1990/teflecher

Também um editor de quiz no formato Teflecher Editor baseado em tecnologias Ionic + Capacitor

Rede:
https://demensdeum.com/software/teflecher-editor/

GitHub:
https://github.com/zefir1990/teflecher-editor

Interpretador de padrões na prática

No último artigo examinamos a teoria do padrão Interpreter, aprendemos o que é uma árvore AST e como abstrair expressões terminais e não terminais. Desta vez, vamos nos afastar da teoria e ver como esse padrão é aplicado em projetos comerciais sérios que todos usamos todos os dias!

Spoiler: Você pode estar usando o padrão Interpreter agora mesmo, apenas lendo este texto no seu navegador!

Um dos exemplos mais marcantes e, talvez, mais importantes do uso desse padrão na indústria é o JavaScript. A linguagem, que originalmente foi criada “no joelho”, hoje funciona em bilhões de dispositivos justamente graças ao conceito de interpretação.

10 dias que mudaram a Internet

A história do JavaScript está cheia de lendas. Em 1995, Brendan Eich, enquanto trabalhava na Netscape Communications, recebeu a tarefa de criar uma linguagem de script simples que pudesse ser executada diretamente em um navegador (Netscape Navigator) para tornar as páginas da web interativas. A administração queria algo com uma sintaxe semelhante ao então super popular Java, mas destinado não a engenheiros profissionais, mas a web designers.

Eich teve apenas 10 dias para escrever o primeiro protótipo da linguagem, que então se chamava Mocha (depois LiveScript, e só depois JavaScript por razões de marketing). A pressa não foi acidental: a Microsoft estava logo atrás, que ao mesmo tempo preparava ativamente sua própria linguagem de script VBScript para ser incorporada no navegador Internet Explorer. A Netscape precisava liberar urgentemente sua resposta para não perder na iminente guerra dos navegadores.

Simplesmente não havia tempo para escrever um compilador complexo em código de máquina. A solução óbvia e mais rápida para Eich foi a arquitetura do clássico Interpreter.

O primeiro intérprete (SpiderMonkey) funcionou assim:

  1. Ele lê o código-fonte do texto do script na página.
  2. O analisador léxico dividiu o texto em tokens.
  3. O analisador construiu uma Árvore de Sintaxe Abstrata (AST). Em termos do padrão Interpreter, esta árvore consistia em expressões terminais (strings, números como 42) e não terminais (chamadas de função, instruções como If, ​​While).
  4. Então a máquina virtual “atravessou” esta árvore passo a passo, executando as instruções embutidas nela em cada nó (chamando um método semelhante a Interpret()).

Contexto e Objetos

Lembra do objeto Context que tivemos que passar para o método Interpret(Context context) na implementação clássica? O intérprete precisa dele para armazenar o estado atual da memória.

No caso do JavaScript, o papel deste contexto no nível superior é desempenhado por um objeto global (por exemplo, uma janela em um navegador). Quando seu nó AST tenta, digamos, escrever texto na tela via document.write(“Hello”), o interpretador acessa seu contexto (o objeto document) e chama a API interna do navegador desejada.

É graças ao interpretador que o JavaScript é capaz de interagir tão facilmente com o DOM (Document Object Model) – todos eles são apenas objetos em um contexto que são acessados ​​por nós de árvore.

Evolução do intérprete: Compilação JIT

Historicamente, JS em navegadores permaneceu por muito tempo um intérprete “puro”. E isso tinha uma grande desvantagem – velocidade lenta. Analisar a árvore e percorrer cada nó lentamente cada vez que o script era executado tornava aplicativos da Web complexos mais lentos.

Com o advento do mecanismo V8 do Google (integrado ao Chrome) em 2008, ocorreu uma revolução. Os engenheiros perceberam que um intérprete não é suficiente para a web moderna. O mecanismo se tornou mais complexo: ele ainda constrói a árvore AST, mas agora usa compilação JIT (Just-In-Time).

Os mecanismos JS modernos (V8, SpiderMonkey) funcionam como um pipeline complexo:

  1. O interpretador base rápido e burro começa a executar seu código JS instantaneamente, sem sequer esperar que ele seja compilado (o padrão clássico ainda funciona aqui).
  2. Paralelamente, o mecanismo monitora seções “quentes” do código (loops ou funções que são chamadas milhares de vezes).
  3. Essas seções são compiladas pelo compilador JIT diretamente no código de máquina otimizado, ignorando o interpretador lento.

Foi essa combinação do início instantâneo do interpretador e do poder computacional de compilação que permitiu que o JavaScript dominasse o mundo, tornando-se a linguagem dos servidores (Node.js) e dos aplicativos móveis (React Native).

Intérprete na indústria de jogos

Apesar do domínio do C++ na computação pesada, o padrão Interpreter é um padrão da indústria no desenvolvimento de jogos para a criação de lógica de jogos. Para que? Para que os designers de jogos possam fazer jogos sem o risco de “deixar cair” o motor ou a necessidade de recompilá-lo constantemente.

Um excelente exemplo histórico é o UnrealScript – a linguagem na qual a lógica dos jogos Unreal Tournament e Gears of War foi escrita no Unreal Engine 1, 2 e 3. O texto foi compilado em um bytecode de máquina abstrato compacto, que foi então passo a passo (interpretado) pela máquina virtual do motor.

Scripts gráficos visuais (Blueprints)

Hoje, o texto foi substituído pela programação visual – o sistema Blueprints no Unreal Engine 4 e 5.

Se você já abriu um Blueprint no Unreal Engine, viu muitos nós conectados por fios. Arquitetonicamente, todo o gráfico do Blueprints é uma enorme Árvore de Sintaxe Abstrata (AST) desenhada na tela:

  1. Expressões de Terminal: Nós constantes. Por exemplo, um nó que simplesmente armazena o número 42 ou uma string. Eles retornam um valor específico quando interpretados.
  2. Expressões não terminais: Nós de computação (Adicionar) ou nós de controle de fluxo (Filial). Eles têm entradas de argumentos, que o intérprete avalia primeiro recursivamente antes de produzir o resultado como um pino de saída.

E o papel do contexto aqui é desempenhado pela memória de uma instância de um objeto de jogo específico (Ator). A Máquina Interpretadora “caminha” com segurança por esse gráfico, solicitando dados e realizando transições.

Onde mais o Interpretador é usado?

O padrão de intérprete pode ser encontrado em quase todos os sistemas complexos onde instruções dinâmicas precisam ser executadas. Aqui estão apenas alguns exemplos de software comercial:

  • Linguagens de programação interpretadas (Python, Ruby, PHP). Todo o seu tempo de execução é baseado no padrão clássico. Por exemplo, a implementação de referência do CPython primeiro analisa seu script .py em um AST, compila-o em bytecode e, em seguida, uma enorme máquina virtual (loop de computação) interpreta esse bytecode passo a passo.
  • Java Virtual Machine (JVM). Inicialmente, o código Java é compilado não em instruções de máquina, mas em bytecode. Quando você executa o aplicativo, a JVM atua como um intérprete (embora com compilação JIT agressiva, assim como na V8).
  • Bancos de dados e SQL Quando você emite uma consulta SQL (SELECT * FROM users) no PostgreSQL ou MySQL, o mecanismo de banco de dados atua como um intérprete. Ele realiza análises lexicais, constrói uma árvore de consulta AST, gera um plano de execução e, em seguida, literalmente “interpreta” esse plano iterando nas linhas das tabelas.
  • Expressões regulares (RegEx). Qualquer mecanismo de expressão regular analisa internamente um padrão de string (por exemplo, ^\d{3}-\d{2}$) em um gráfico de estado (NFA/DFA Automata), pelo qual o interpretador interno passa, combinando cada caractere de entrada com os vértices deste gráfico.
  • Unity Shader Graph / Unreal Material Editor – interpreta nós visuais em código de shader modular (GLSL/HLSL).
  • Nós de geometria do Blender – interpreta operações matemáticas e geométricas para gerar modelos 3D de forma processual em tempo real.

Total

O padrão Interpreter já ultrapassou o escopo de “escrever sua própria calculadora”. Este é o padrão mais poderoso da indústria. Desde mecanismos JavaScript que executam gigabytes de código nos bastidores dos navegadores todos os dias até designers de jogos que permitem construir lógica complexa sem conhecimento de C++, os intérpretes continuam sendo um dos conceitos de arquitetura mais importantes no desenvolvimento de TI moderno.

Glazki TV: reprodutor moderno para televisão pela Internet

Glazki TV é um player moderno e de alto desempenho para televisão pela Internet (IPTV), construído com base em React Native e Expo. O projeto está focado na facilidade de uso e rapidez, proporcionando uma interface conveniente para visualização de canais de IPTV tanto em dispositivos móveis quanto no navegador.

Principais características

  • 📺 Navegação por canais: navegue por milhares de canais, categorizados para facilitar a navegação.
  • 🔍 Pesquisa: encontre rapidamente os canais que você precisa por nome.
  • ❤️ Favoritos: salve seus canais favoritos para acesso rápido (dados salvos localmente).
  • 🔗 Deep Linking: compartilhe links diretos para canais que abrem automaticamente.
  • 🌓 Suporte ao tema: A interface se adapta automaticamente ao tema claro ou escuro do sistema.
  • 🌐 Suporte Web: O player é totalmente funcional no navegador com sincronização de URL.

Pilha de tecnologia

O projeto é baseado em modernas ferramentas de desenvolvimento:

  • Estrutura: React Native + Expo
  • Video Player: expo-video (замена устаревшему expo-av)
  • Kit de ferramentas de IU: react-native-paper
  • Analisador de lista de reprodução: iptv-playlist-parser

Versão web:
https://demensdeum.com/software/glazki-tv/

Versão do GooglePlay:
https://play.google.com/store/apps/details?id=com.demensdeum.glazkitv

O projeto continua a se desenvolver e eu gostaria de receber qualquer feedback!

Aço Flamejante: Máscara da Morte 2

Nas profundezas escuras e cintilantes do submundo digital, um novo desafio o aguarda. Estamos entusiasmados em abrir a cortina de Flame Steel: Death Mask 2, um rastreador de masmorras 3D multijogador que combina a estética retro-cyberpunk com jogabilidade moderna em tempo real.

🕹️ O que é Flame Steel: Death Mask 2?

Imagine acordar em um labirinto gerado processualmente onde cada sombra pode ser outro jogador ou uma entidade hostil de “Filtro”. Flame Steel: Death Mask 2 coloca você na pele de um Seeker, navegando em um mundo construído no Flame Steel Engine 2 e Three.js.

O jogo está atualmente em seus estágios iniciais de desenvolvimento, mas a experiência principal já está ativa e pronta para exploração.

🚀 Principais recursos

  • Exploração Multijogador: Você não está sozinho na grade. Veja outros jogadores em tempo real enquanto navega pelos corredores labirínticos.
  • Masmorras Procedurais: Não há duas execuções iguais. O servidor gera novos mapas cheios de mistério e perigo.
  • O Terminal: para aqueles que preferem uma abordagem mais prática, uma interface de linha de comando integrada permite que você interaja diretamente com o sistema: execute ações avançadas, depure ou simplesmente converse com outros Seekers.
  • Combate e Combate Sobrevivência: enfrente filtros para ganhar bits e, em seguida, use-os para desbloquear baús e atualizar suas estatísticas. Fique de olho na sua saúde; a sobrevivência não é garantida.
  • Estética Retro-Cyberpunk: visuais de alto contraste e uma atmosfera corajosa que homenageia a era clássica do cyberpunk.

🛠️ A tecnologia por trás da máscara

Construído para o navegador, o jogo aproveita:

  • Frontend: Vanilla JavaScript e Three.js para renderização 3D suave.
  • Back-end: Node.js e WebSockets (ws) para sincronização multijogador extremamente rápida.
  • Infraestrutura: MongoDB para persistência de dados e Redis para indexação espacial em tempo real.

🗺️ O que vem a seguir?

Estamos apenas começando. Como um projeto de acesso antecipado, Máscara da Morte 2 receberá atualizações frequentes, incluindo:

  • Novos tipos de entidades e mecânicas de combate complexas.
  • Conhecimento mais profundo e narrativa ambiental.
  • Comandos de terminal e recursos sociais aprimorados.
  • Aperfeiçoamento visual e de desempenho.

🔗 Junte-se à Rede

Quer testar sua coragem? Digite seu codinome e inicialize sua identidade hoje:

👉 Jogar Flame Steel: Death Mask 2

Fique ligado para mais atualizações à medida que continuamos a expandir a fronteira digital. Bem-vindo ao serviço. Isso exige você.

Rádio Ushka

Ushki-Radio é um reprodutor de rádio multiplataforma para rádio online, feito com foco na simplicidade e no prazer de ouvir. Sem funções desnecessárias, sem interfaces sobrecarregadas – basta ligá-lo e ouvir.


https://demensdeum.com/software/ushki-radio

O projeto utiliza o Radio Browser de código aberto, disponibilizando no aplicativo milhares de rádios de todo o mundo. Você pode procurá-los por nome, gênero ou popularidade, adicioná-los aos seus favoritos e retornar rapidamente às suas estações favoritas.

Ushki-Radio é perfeito para o papel de reprodutor de rádio de fundo: lembra a última estação, permite controlar o volume e não requer configurações complexas. A interface é concisa e intuitiva – tudo é feito para que nada distraia a música, as conversas e a transmissão.

Tecnicamente, o projeto é construído em React Native e Expo, portanto funciona tanto no navegador quanto como aplicativo nativo. Nos bastidores, o expo-av é usado para reproduzir áudio e as configurações do usuário são armazenadas localmente. Há suporte para vários idiomas, incluindo russo e inglês.

Ushki-Radio é um bom exemplo do que um reprodutor de rádio moderno na Internet pode ser: aberto, leve, expansível e focado principalmente no ouvinte. O projeto é distribuído sob licença do MIT e é perfeito tanto para uso pessoal quanto como base para seus próprios experimentos com aplicativos de áudio.

Github:
https://github.com/demensdeum/Ushki-Radio

cobertura

Coverseer – observador inteligente de processos usando LLM

Coverseer é uma ferramenta Python CLI para monitorar de forma inteligente e reiniciar processos automaticamente. Ao contrário das soluções clássicas de watchdog, ele analisa a saída de texto do aplicativo usando o modelo LLM e toma decisões com base no contexto, não apenas no código de saída.

O projeto é de código aberto e está disponível no GitHub:
https://github.com/demensdeum/coverseer

O que é o Coverser

O Coverseer inicia o processo especificado, monitora continuamente seu stdout e stderr, alimenta os últimos pedaços de saída para o LLM local (via Ollama) e determina se o processo está no estado de execução correto.

Se o modelo detectar um erro, congelamento ou comportamento incorreto, o Coverseer encerra automaticamente o processo e o inicia novamente.

Principais recursos

  • Análise contextual da saída – em vez de verificar o código de saída, a análise de log é usada usando LLM
  • Reinicialização automática – o processo é reiniciado quando problemas ou encerramento anormal são detectados
  • Trabalhar com modelos locais – Ollama é usado, sem transferir dados para serviços externos
  • Registro detalhado – todas as ações e decisões são registradas para diagnósticos subsequentes
  • Execução autônoma – pode ser compactada em um único arquivo executável (por exemplo, .exe)

Como funciona

  1. Coverseer executa o comando passado pela CLI
  2. Coleta e armazena em buffer a saída de texto do processo
  3. Envia as últimas linhas para o modelo LLM
  4. Obtém uma avaliação semântica do estado do processo
  5. Se necessário, finaliza e reinicia o processo

Essa abordagem permite identificar problemas que não podem ser detectados por ferramentas de monitoramento padrão.

Requisitos

  • Python 3.12 ou posterior
  • Ollama instalado e funcionando
  • Modelo carregado gemma3:4b-it-qat
  • Dependências do Python: solicitações, ollama-call

Usar exemplo


python coverseer.py “seu comando aqui”

Por exemplo, observando o carregamento do modelo Ollama:


python coverseer.py “ollama pull gemma3: 4b-it-qat”

O Coverseer analisará a saída do comando e responderá automaticamente a falhas ou erros.

Aplicação prática

O Coverseer é especialmente útil em cenários onde os mecanismos de supervisão padrão são insuficientes:

  • Pipelines de CI/CD e compilações automáticas
  • Serviços e agentes em segundo plano
  • Processos experimentais ou instáveis
  • Ferramentas com grandes quantidades de registros de texto
  • Ambientes de desenvolvimento onde a autocorreção é importante

Por que a abordagem LLM é mais eficaz

Os sistemas de monitoramento clássicos respondem aos sintomas. Coverser analisa o comportamento. O modelo LLM é capaz de reconhecer erros, avisos, falhas repetidas e becos sem saída lógicos mesmo nos casos em que o processo continua formalmente a operar.

Isso torna o monitoramento mais preciso e reduz o número de alarmes falsos.

Conclusão

Coverseer é um exemplo claro da aplicação prática do LLM em DevOps e tarefas de automação. Ele expande a compreensão tradicional do monitoramento de processos e oferece uma abordagem mais inteligente e baseada no contexto.

O projeto será de particular interesse para desenvolvedores que estão experimentando ferramentas de IA e procurando maneiras de melhorar a estabilidade de seus sistemas sem complicar a infraestrutura.

Aço Flamejante: Mineiros de Marte

Flame Steel: Mars Miners é um jogo de estratégia tática com ritmo incomum e ênfase na tomada de decisões em vez de reflexos. O jogo se passa em Marte, onde os jogadores competem pelo controle de recursos e territórios diante de informações limitadas e da pressão constante dos rivais.

A jogabilidade é baseada na construção de estações centrais que formam a infraestrutura de sua expedição. Os nós permitem extrair recursos, expandir sua zona de influência e construir logística. Cada posicionamento é importante: um erro pode abrir o caminho do inimigo para setores-chave ou privá-lo de uma vantagem estratégica.

O ritmo do jogo é deliberadamente controlado e intenso. Está em algum lugar entre o xadrez, o Go e o combate naval: o posicionamento, a previsão das ações do oponente e a capacidade de trabalhar com a incerteza são importantes aqui. Parte do mapa e as intenções do inimigo permanecem ocultas, por isso o sucesso depende não só do cálculo, mas também da leitura da situação.

Flame Steel: Mars Miners suporta jogo online, o que torna cada jogo único – as estratégias evoluem e o meta está sendo formado agora. O jogo está em um estágio inicial de desenvolvimento e este é o seu ponto forte: os jogadores têm a oportunidade de ser os primeiros a mergulhar em um projeto novo e fora do padrão, influenciar seu desenvolvimento e descobrir mecânicas que não copiam os modelos usuais do gênero.

Se você está interessado em jogos táticos com profundidade, design experimental e ênfase no pensamento, vale a pena conferir Flame Steel: Mars Miners agora.

REGRAS DO JOGO

* O campo de jogo consiste em células nas quais os jogadores colocam seus objetos um por um. Em cada turno, um jogador pode realizar uma ação de construção.

* Apenas dois tipos de objetos podem ser construídos: estações centrais e minas. Qualquer construção é possível exclusivamente em uma célula livre localizada próximo a um nó de jogador existente, vertical ou horizontalmente. A colocação diagonal não é permitida.

* As estações centrais constituem a base do controle territorial e servem como pontos de expansão. As minas são colocadas de acordo com as mesmas regras, mas são contadas como objetos de recursos e afetam diretamente o resultado final da festa.

* Se um jogador construir uma linha contínua de suas estações nodais vertical ou horizontalmente, tal linha automaticamente se transforma em uma arma. A arma permite atacar o inimigo e destruir sua infraestrutura.

* Para disparar uma arma, o jogador seleciona uma célula pertencente à sua arma e aponta para qualquer estação de nó inimigo no campo. A estação do nó inimigo selecionada é destruída e removida do campo de jogo. As minas não podem ser atacadas diretamente – apenas através da destruição dos nós que fornecem acesso a elas.

* O jogo continua até o final definido do jogo. O vencedor é o jogador que neste momento tiver o maior número de minas de recursos no campo de jogo. Em caso de igualdade, o fator decisivo pode ser o controle do território ou condições adicionais determinadas pelo modo de jogo.

https://mediumdemens.vps.webdock.cloud/mars-miners

Antigravidade

Em alguns dias, com a ajuda do Antigravity, transferi o backend Masonry-AR de PHP + MySQL para Node.js + MongoDB + Redis -> Docker. As capacidades da IA ​​são realmente incríveis, lembro-me de como em 2022 escrevi os shaders mais simples em shadertoy.com via ChatGPT e parecia que este brinquedo não poderia fazer nada superior.
https://www.shadertoy.com/view/cs2SWm

Quatro anos depois, observo como, em cerca de 10 prompts, transferi meu projeto sem esforço de uma plataforma traseira para outra, adicionando conteinerização.
https://mediumdemens.vps.webdock.cloud/masonry-ar/

Legal, muito legal.

Conselho Kaban

KabanBoard é um aplicativo web de código aberto para gerenciamento de tarefas no formato Kanban. O projeto está focado na simplicidade, arquitetura compreensível e possibilidade de modificação para tarefas específicas de uma equipe ou de um desenvolvedor individual.

A solução é adequada para pequenos projetos, processos internos de equipe ou como base para seu próprio produto, sem estar vinculada a serviços SaaS de terceiros.

O repositório do projeto está disponível no GitHub:
https://github.com/demensdeum/KabanBoard

Principais características

KabanBoard implementa um conjunto básico e prático de funções para trabalhar com quadros Kanban.

  • Criação de vários quadros para diferentes projetos
  • Estrutura de colunas com status de tarefas
  • Cartões de tarefas com capacidade de editar e excluir
  • Mover tarefas entre colunas (arrastar e soltar)
  • Codificação de cores dos cartões
  • Tema de interface escuro

A funcionalidade não fica sobrecarregada e está focada no trabalho diário com tarefas.

Tecnologias utilizadas

O projeto é construído em uma pilha comum e compreensível.

  • Front-end:Vue 3, Vite
  • Back-end: Node.js, Express
  • Armazenamento de dados: MongoDB

As partes cliente e servidor são separadas, o que simplifica o suporte e o desenvolvimento do projeto.

Implantação do projeto

Para executar localmente, você precisará de um ambiente padrão.

  • Node.js
  • MongoDB (localmente ou via nuvem)

O projeto pode ser iniciado no modo normal via npm ou usando Docker, o que é conveniente para implantação rápida em um ambiente de teste ou interno.

Aplicação prática

KabanBoard pode ser usado em diferentes cenários.

  • Ferramenta interna de gerenciamento de tarefas
  • Base para uma solução Kanban personalizada
  • Projeto de formação para estudo de arquitetura SPA
  • Ponto de partida para um projeto ou portfólio favorito

Conclusão

KabanBoard é uma solução simples e prática para trabalhar com quadros Kanban. O projeto não pretende substituir grandes sistemas corporativos, mas é adequado para pequenas equipes, uso individual e desenvolvimento adicional para tarefas específicas.

Gofis

Gofis é uma ferramenta leve de linha de comando para pesquisar arquivos rapidamente no sistema de arquivos.
Está escrito em Go e faz uso intenso de paralelismo (goroutines), o que o torna especialmente eficiente
ao trabalhar com grandes diretórios e projetos.

O projeto está disponível no GitHub:
https://github.com/demensdeum/gofis

🧠 O que são Gofis

Gofis é um utilitário CLI para pesquisar arquivos por nome, extensão ou expressão regular.
Ao contrário de ferramentas clássicas como find, o gofis foi originalmente projetado
com ênfase em velocidade, saída legível e processamento de diretório paralelo.

O projeto é distribuído sob licença do MIT e pode ser usado gratuitamente
para fins pessoais e comerciais.

⚙️ Principais recursos

  • Travessia de diretório paralelo usando goroutines
  • Pesquise por nome de arquivo e expressões regulares
  • Filtrar por extensões
  • Ignorando diretórios pesados ​​(.git, node_modules, vendor)
  • Saída legível de tamanhos de arquivo
  • Dependências mínimas e construção rápida

🚀 Instalação

Requer Go instalado para funcionar.

git clone https://github.com/demensdeum/gofis
cd gofis
go build -o gofis main.go

Uma vez construído, o binário pode ser usado diretamente.

Há também uma versão autônoma para versões modernas do Windows na página de lançamentos:
https://github.com/demensdeum/gofis/releases/

🔍 Exemplos de uso

Pesquise arquivos por nome:

./gofis -n "config" -e ".yaml" -p ./src

Pesquisa posicional rápida:

./gofis "main" "./projects" 50

Pesquise usando expressão regular:

./gofis "^.*\.ini$" "/"

🧩 Como funciona

Gofis é baseado no modelo competitivo de Go:

  • Cada diretório é processado em uma goroutine separada
  • Usa um semáforo para limitar o número de tarefas ativas
  • Canais são usados ​​para transmitir resultados de pesquisa

Esta abordagem permite o uso eficiente dos recursos da CPU
e acelera significativamente a pesquisa em grandes árvores de arquivos.

👨‍💻 Para quem o Gofis é adequado?

  • Desenvolvedores que trabalham com repositórios grandes
  • DevOps e administradores de sistema
  • Usuários que precisam de uma pesquisa rápida no terminal
  • Para quem está aprendendo os usos práticos da simultaneidade em Go

📌 Conclusão

Gofis é uma ferramenta simples, mas eficaz, que faz uma coisa e faz bem.
Se você costuma pesquisar arquivos em grandes projetos e valoriza a velocidade,
esta ferramenta CLI definitivamente vale a pena dar uma olhada.

chamada de ollama

Se você usa Ollama e não quer escrever seu próprio wrapper de API todas as vezes,
o projeto ollama_call simplifica significativamente o trabalho.

Esta é uma pequena biblioteca Python que permite enviar uma solicitação para um LLM local com uma função
e receba imediatamente uma resposta, inclusive no formato JSON.

Instalação

pip install ollama-call

Por que é necessário

  • código mínimo para trabalhar com o modelo;
  • resposta JSON estruturada para processamento posterior;
  • conveniente para protótipos rápidos e MVPs;
  • suporta saída de streaming, se necessário.

Usar exemplo

from ollama_call import ollama_call

response = ollama_call(
    user_prompt="Hello, how are you?",
    format="json",
    model="gemma3:12b"
)

print(response)

Quando é especialmente útil

  • você escreve scripts ou serviços em cima do Ollama;
  • precisa de um formato de resposta previsível;
  • não há desejo de conectar estruturas pesadas.

Total

ollama_call é um wrapper leve e claro para trabalhar com Ollama do Python.
Uma boa escolha se simplicidade e resultados rápidos forem importantes.

GitHub
https://github.com/demensdeum/ollama_call

SFAP: uma estrutura modular para aquisição e processamento de dados modernos

No contexto do desenvolvimento ativo da automação e da inteligência artificial, a tarefa de coletar efetivamente,
Limpar e transformar dados torna-se fundamental. A maioria das soluções apenas fecha
etapas separadas deste processo, exigindo integração e suporte complexos.

SFAP (Seek · Filter · Adapt · Publish) é um projeto de código aberto em Python,
que oferece uma abordagem holística e extensível ao processamento de dados em todas as fases do seu ciclo de vida:
desde a busca de fontes até a publicação do resultado final.

O que é SFAP

SFAP é uma estrutura assíncrona construída em torno de um conceito claro de pipeline de processamento de dados.
Cada estágio é logicamente separado e pode ser expandido ou substituído de forma independente.

O projeto é baseado no padrão arquitetônico Chain of Responsibility, que fornece:

  • Flexibilidade de configuração de pipeline;
  • teste simples de estágios individuais;
  • escalabilidade para cargas altas;
  • separação clara de responsabilidades entre componentes.

Principais etapas do pipeline

Busca – pesquisa de dados

Nesta fase, as fontes de dados são descobertas: páginas web, APIs, armazenamentos de arquivos
ou outros fluxos de informação. O SFAP facilita a conexão de novas fontes sem alterar
o resto do sistema.

Filtro – filtragem

A filtragem foi projetada para remover ruídos: conteúdo irrelevante, duplicatas, elementos técnicos
e dados de baixa qualidade. Isto é crítico para as etapas de processamento subsequentes.

Adaptar – adaptação e processamento

A etapa de adaptação é responsável pela transformação dos dados: normalização, estruturação,
processamento semântico e integração com modelos de IA (inclusive generativos).

Publicar – publicação

Na fase final, os dados são publicados no formato alvo: bancos de dados, APIs, arquivos, serviços externos
ou plataformas de conteúdo. O SFAP não limita a forma como o resultado é entregue.

Principais características do projeto

  • Arquitetura assíncrona baseada em asyncio
  • Modularidade e extensibilidade
  • Suporte para pipelines de processamento complexos
  • Pronto para integração com soluções AI/LLM
  • Adequado para sistemas altamente carregados

Casos de uso práticos

  • Agregação e análise de fontes de notícias
  • Preparando conjuntos de dados para aprendizado de máquina
  • Pipeline de conteúdo automatizado
  • Limpar e normalizar grandes fluxos de dados
  • Integração de dados de fontes heterogêneas

Introdução ao SFAP

Tudo que você precisa para começar é:

  1. Clone o repositório do projeto;
  2. Instalar dependências do Python;
  3. Defina suas próprias etapas de pipeline;
  4. Iniciar um processo de processamento de dados assíncrono.

O projeto é facilmente adaptado a tarefas específicas do negócio e pode crescer com o sistema,
sem se transformar em um monólito.

Conclusão

SFAP não é apenas um analisador ou coletor de dados, mas uma estrutura completa para construir
sistemas modernos de pipeline de dados. É adequado para desenvolvedores e equipes que se preocupam com
escalável, arquitetonicamente limpo e pronto para dados.
O código-fonte do projeto está disponível no GitHub:
https://github.com/demensdeum/SFAP

FlutDataStream

Um aplicativo Flutter que converte qualquer arquivo em uma sequência de códigos legíveis por máquina (QR e DataMatrix) para streaming de dados em alta velocidade entre dispositivos.

Peculiaridades
* Codificação dupla: representa cada bloco de dados como um código QR e um código DataMatrix.
* Streaming de alta velocidade: Suporta intervalo de comutação automática de até 330ms.
* Smart Chunking: divide automaticamente os arquivos em partes personalizadas (padrão: 512 bytes).
* Scanner detalhado: leia o código ASCII em tempo real para depuração e feedback instantâneo.
* Recuperação automática: recupera e salva arquivos instantaneamente em seu diretório de downloads.
* Integração do sistema: abre automaticamente o arquivo salvo usando o aplicativo de sistema padrão após a conclusão.

https://github.com/demensdeum/FlutDataStream

Por que não consigo corrigir o bug?

Você passa horas trabalhando no código, analisando hipóteses, ajustando as condições, mas o bug ainda é reproduzido. Parece familiar? Esse estado de frustração costuma ser chamado de “caça aos fantasmas”. O programa parece viver sua própria vida, ignorando suas correções.

Um dos motivos mais comuns – e mais irritantes – para essa situação é procurar um erro no lugar completamente errado do aplicativo.

A armadilha dos “falsos sintomas”

Quando vemos um erro, nossa atenção é atraída para o local onde ele “disparou”. Mas em sistemas complexos, onde ocorre um bug (travamento ou valor incorreto) é apenas o fim de uma longa cadeia de eventos. Ao tentar consertar o final, você está lutando contra os sintomas, não contra a doença.

É aqui que entra o conceito de fluxograma.

Como funciona na realidade

Claro, não é necessário desenhar (desenhar) diretamente um fluxograma no papel todas as vezes, mas é importante tê-lo em mente ou em mãos como um guia arquitetônico. Um fluxograma permite visualizar a operação de um aplicativo como uma árvore de resultados.

Sem compreender essa estrutura, o desenvolvedor muitas vezes fica tateando no escuro. Imagine a situação: você edita a lógica em uma ramificação de condição, enquanto a aplicação (devido a um determinado conjunto de parâmetros) vai para uma ramificação completamente diferente na qual você nem pensou.

Resultado: você gasta horas em uma correção de código “perfeita” em uma parte do algoritmo, o que, é claro, não faz nada para corrigir o problema em outra parte do algoritmo onde ele realmente falha.


Algoritmo para derrotar um bug

Para parar de bater em uma porta fechada, você precisa mudar sua abordagem ao diagnóstico:

  • Encontre o estado na árvore de resultados:Antes de escrever o código, você precisa determinar exatamente o caminho que o aplicativo seguiu. Em que ponto a lógica tomou o rumo errado? Que estado específico (Estado) levou ao problema?
  • A reprodução tem 80% de sucesso: Isso geralmente é feito por testadores e testes automatizados. Se o bug estiver “flutuante”, o desenvolvimento estará envolvido no processo de busca conjunta de condições.
  • Use o máximo de informações possível: registros, versão do sistema operacional, parâmetros do dispositivo, tipo de conexão (Wi-Fi/5G) e até mesmo uma operadora de telecomunicações específica são importantes para a localização.

“Fotografia” do momento do erro

Idealmente, para corrigi-lo, você precisa obter o estado completo do aplicativo no momento em que o bug foi reproduzido. Os logs de interação também são extremamente importantes: eles mostram não apenas o ponto final, mas também todo o caminho do usuário (quais ações precederam a falha). Isso ajuda a entender como recriar um estado semelhante novamente.

Dica futura: se você encontrar um caso complexo, adicione informações estendidas de registro de depuração a esta seção do código, caso a situação aconteça novamente.


O problema dos estados “indescritíveis” na era da IA

Em sistemas modernos que usam LLM (Large Language Models), o determinismo clássico (“uma entrada, uma saída”) é frequentemente violado. Você pode passar exatamente os mesmos dados de entrada, mas obter um resultado diferente.

Isso acontece devido ao não determinismo dos sistemas de produção modernos:

  • Paralelismo de GPU: as operações de ponto flutuante da GPU nem sempre são associativas. Devido à execução paralela de threads, a ordem em que os números são adicionados pode mudar ligeiramente, o que pode afetar o resultado.
  • Temperatura e aceleração da GPU: a velocidade de execução e a distribuição de carga podem depender do estado físico do hardware. Em modelos enormes, essas diferenças microscópicas se acumulam e podem levar à seleção de um token diferente na saída.
  • Lote dinâmico: Na nuvem, sua solicitação é combinada com outras. Diferentes tamanhos de lote alteram a matemática dos cálculos nos kernels.

Sob tais condições, torna-se quase impossível reproduzir “esse mesmo estado”. Somente uma abordagem estatística aos testes pode salvá-lo aqui.


Quando a lógica falha: problemas de memória

Se você estiver trabalhando com linguagens “inseguras” (C ou C++), o bug pode ocorrer devido a corrupção de memória.

Esses são os casos mais graves: um erro em um módulo pode “sobrescrever” dados em outro. Isso leva a falhas completamente inexplicáveis ​​e isoladas que não podem ser rastreadas usando a lógica normal do aplicativo.

Como se proteger no nível arquitetônico?

Para evitar esses bugs “místicos”, você deve usar abordagens modernas:

  • Padrões de programação multithread:a sincronização clara elimina condições de corrida.
  • Linguagens thread-safe: Ferramentas que garantem a segurança da memória em tempo de compilação:
    • Rust: o sistema de propriedade elimina erros de memória.
    • Simultaneidade Swift 6:fortes verificações de isolamento de dados.
    • Erlang: isolamento completo do processo por meio do modelo de ator.

Resumo

Consertar um bug não é escrever um novo código, mas entender como o antigo funciona. Lembre-se: você pode estar perdendo tempo editando uma branch que a administração nem sequer toca. Registre o estado do sistema, leve em consideração o fator de não determinismo da IA ​​e escolha ferramentas seguras.

Ferral

Ferral é uma linguagem de programação multiparadigma de alto nível projetada especificamente para gerar código a partir de grandes modelos de linguagem (LLMs). Embora as linguagens tradicionais tenham sido projetadas com a ergonomia humana em mente, Ferral é otimizado para como os grandes modelos de linguagem (LLMs) raciocinam, tokenizam e inferem lógica.

O nome é escrito com dois R, indicando uma abordagem “reimaginada” para a natureza imprevisível do código gerado por IA.

https://github.com/demensdeum/ferral

Desafio de codificação DemensDeum nº 2

Estou iniciando o Desafio de Codificação Demensdeum nº 2:
1. Você precisa vibrar o aplicativo web para exibir uma lista de festas/eventos na área do usuário.
2. A fonte de dados pode ser web scraping frontal ou um banco de dados local/remoto.
3. Mostrar eventos/festas no mapa apenas para hoje.
4. Você pode alterar o raio de pesquisa.
5. Envie como uma sequência de prompts de texto que podem ser reproduzidos em geradores de código gratuitos, como o Google AI Studio.
6. Deve funcionar na web para iOS, Android, PC
7. O melhor design vence
8. Exiba informações detalhadas sobre o evento tocando no evento no mapa.
9. Amplie mapas com os dedos ou o mouse.
10. O vencedor é escolhido pelo júri (escreva-me para participar do júri)
11. Prêmio 200 USDT
12. Data de vencimento: 1º de julho.

Vencedor do último DemensDeum Coding Challenge #1
https://demensdeum.com/blog/ru/2025/06/03/demensdeum-code-challenge-1-winner/

Atualização de alvenaria-AR

A capacidade de comprar moedas por criptomoeda foi adicionada ao jogo Masonry-AR! Por US$ 1 você pode obter 5.000 MOS. Links de referência também foram adicionados ao jogo; para cada compra de um amigo, o indicador recebe 50.000 MOS. Detalhes no Wiki Maçônico. Também foi adicionado um modo de caminhada automática: quando não há acesso ao módulo GPS, o Mason começa a caminhar de uma das capitais do mundo automaticamente, apenas para frente.

Link do jogo:
https://demensdeum.com/demos/masonry-ar/client/

Adepto do Burro

“Donkey Adept” é uma peça impressionante e eletrizante de surrealismo pixelado. No centro está uma figura com uma jaqueta de couro preta, cuja cabeça é uma televisão em chamas e cheia de estática, com orelhas de burro em chamas. O sujeito segura uma lanterna poderosa, agindo como um sentinela solitário que busca a verdade em meio ao barulho. É uma meditação furiosa em estilo retrô sobre a mídia, a loucura e a busca incansável pela luz.

https://opensea.io/item/ethereum/0x008d50b3b9af49154d6387ac748855a3c62bf40d/5

Cube Art Project 2 online

Conheça o Cube Art Project 2 Online – Editor leve, rápido e totalmente reescrito da programação da estação, que funciona diretamente no navegador. Agora, com a possibilidade de criatividade conjunta!

Isso não é apenas uma ferramenta, mas um experimento com cor, geometria e uma criação 3D meditativa à qual você pode conectar amigos. O projeto foi criado em JavaScript Pure e três.js sem estruturas e membros da Web, demonstrando os recursos de WebGL e Shaaders.

NOVO: Multiplayer! Cooperar com outros usuários em tempo real. Todas as mudanças, a adição e coloração dos cubos são sincronizadas instantaneamente, permitindo que você crie obras -primas da estação.

Controlar:
– WASD – movendo a câmera
– Mouse – rotação
– GUI – Configurações de cores

On-line:
https://demensdeum.com/software/cube-art-project-2-online/

Fontes no Github:
https://github.com/demensdeum/cube-art-project-2-online

O projeto é escrito em JavaScript puro usando três.js.
Sem estruturas, sem colecionadores, sem o WebAssembly – apenas Webgl, Shaders e um pouco de amor pela geometria de pixels.

Donki Hills Steam

Donki Hills é um jogo de terror de comédia, uma experiência narrativa emocionante na primeira pessoa, mergulhando os jogadores em um profundo segredo com uma mistura de humor inesperado. Desenvolvido e publicado por Demensdeum no motor Unreal Engine, o jogo permite controlar James, uma pessoa comum, cuja vida dá uma virada incomum após o misterioso desaparecimento de seu conhecido online, Maria. Sua única pista é uma única foto sugerindo uma vila russa isolada chamada Quiet Donki, localizado perto de Novosibirsk. Dirigindo com uma conexão inabalável e uma necessidade desesperada de respostas (e, possivelmente, com várias risadas nervosas), James faz uma jornada épica para revelar a verdade sobre o desaparecimento de Maria.

O jogo está disponível no Steam:
https://store.steampowered.com/app/3476390/Donki_Hills/

Entropia em programação

[Complementos]

A entropia na programação é uma força poderosa, mas muitas vezes discreta, que determina a variabilidade e a imprevisibilidade do comportamento do software. De bugs simples a avós complexas, a entropia é a razão pela qual nossos programas nem sempre se comportam como esperamos.

O que é entropia no software?

A entropia no software é uma medida de resultados inesperados de algoritmos. O usuário percebe os resultados 1stti como erros ou bugs, mas do ponto de vista da máquina, o algoritmo executa exatamente as instruções que o programador estabeleceu nele. O comportamento inesperado surge devido a um grande número de combinações possíveis de dados de entrada, condições do sistema e interações.

Causas de entropia:

* Alterando o estado: quando o objeto pode alterar seus dados internos, o resultado de seu trabalho se torna dependente de todo o histórico de seu uso.

* A complexidade dos algoritmos: à medida que o programa cresce, o número de maneiras possíveis de executar o código cresce exponencialmente, o que torna quase impossível a previsão de todos os resultados.

* Fatores externos: sistema operacional, outros programas, atrasos na rede – tudo isso pode afetar a execução do seu código, criando fontes adicionais de variabilidade.

Causas de entropia:

* Alterando o estado: quando o objeto pode alterar seus dados internos, o resultado de seu trabalho se torna dependente de todo o histórico de seu uso.

* A complexidade dos algoritmos: à medida que o programa cresce, o número de maneiras possíveis de executar o código cresce exponencialmente, o que torna quase impossível a previsão de todos os resultados.

* Fatores externos: sistema operacional, outros programas, atrasos na rede – tudo isso pode afetar a execução do seu código, criando fontes adicionais de variabilidade.

Variáveis globais como fonte de entropia

Em seu trabalho, “Global Varia Bybles Conseded Liveful” (1973) W.A. Wulf e M. Shaw mostraram que as variáveis globais são uma das principais fontes de comportamento imprevisível. Eles criam vícios implícitos e efeitos colaterais difíceis de rastrear e controlar, que é uma manifestação clássica da entropia.

Leis de Leman e Entropy

A idéia de crescente complexidade dos sistemas de software formulou perfeitamente Manny Leman em suas leis de evolução do software. Dois deles refletem diretamente o conceito de entropia:

O programa de computador usado será modificado. Esta declaração sugere que o software não é estático. Ele vive, desenvolve e muda para atender a novos requisitos e meio ambiente. Cada nova “rodada” da vida do programa é uma fonte potencial de entropia.

Quando o programa de computador é modificado, sua complexidade aumenta, desde que ninguém impeça isso. Esta lei é uma conseqüência direta da entropia. Sem esforços direcionados de gerenciamento de complexidade, cada nova modificação introduz variabilidade adicional e imprevisibilidade no sistema. Existem novas dependências, condições e efeitos colaterais que aumentam a probabilidade de bugs e comportamento não obsoleto.

entropia no mundo da IA e LLM: código imprevisível

No campo da inteligência artificial e dos grandes modelos de idiomas (LLM), a entropia é especialmente aguda, pois aqui estamos lidando com algoritmos não -metâmicos. Ao contrário dos programas tradicionais, onde o mesmo acesso sempre oferece a mesma saída, o LLM pode fornecer respostas diferentes para a mesma solicitação.

Isso cria um enorme problema: a correção do algoritmo pode ser confirmada apenas em um determinado conjunto limitado de dados de entrada usando autores. Mas ao trabalhar com dados de entrada desconhecidos (solicitações dos usuários), o comportamento do modelo se torna imprevisível.

Exemplos de entropia em LLM

Vocabulário e declarações racistas e inordenadas: casos conhecidos quando os bots de bate -papo, como Tay da Microsoft ou Grok de XII, depois de treinar dados da Internet, começaram a gerar declarações ofensivas ou racistas. Este foi o resultado da entropia: dados de entrada desconhecidos em combinação com um enorme volume de amostra de treinamento levou a um comportamento imprevisível e incorreto.

Apelações ilegais: esses problemas surgem quando uma rede neural começa a emitir conteúdo que viola direitos autorais ou normas éticas.

Ai Bota nos Jogos: A introdução de personagens de IA em jogos com a possibilidade de aprender, por exemplo, em Fortnite, levou ao fato de que a IA Bot teve que ser desligada e adicionada ao rastreamento da correção da atividade, para impedir que ações ilegais do LLM Bot.

Dívida técnica: juros acumulados em defeitos

Código mal escrito e soluções de desvio
O dever técnico é um compromisso consciente ou inconsciente, no qual é dada prioridade à entrega rápida em detrimento do apoio e qualidade a longo prazo. Correções rápidas e soluções de desvio sem documentos, geralmente implementadas em pouco tempo, acumulam, formando um “campo minado”. Isso torna a base de código extremamente sensível, mesmo para pequenas alterações, uma vez que se torna difícil distinguir soluções de desvio intencional da lógica errônea real, o que leva a regressão inesperada e um aumento no número de erros.

Isso demonstra o efeito direto e cumulativo do dever técnico sobre a propagação de erros e a integridade dos algoritmos, onde cada redução atual adota leva a erros mais complexos e frequentes no futuro.

testes inadequados e seu efeito cumulativo

Quando os sistemas de software não são testados com cuidado, eles são muito mais suscetíveis a erros e comportamento inesperado. Essa inadequação permite que os erros se acumulem com o tempo, criando um sistema difícil de suportar e que é muito suscetível a outros erros. Negligenciar os testes desde o início não apenas aumenta a dívida técnica, mas também ajuda diretamente a aumentar o número de erros. A “teoria das janelas quebradas” na entropia de software sugere que erros insignificantes, ignorados ou problemas de design podem se acumular ao longo do tempo e levar a problemas mais sérios e reduzir a qualidade do software.

Isso estabelece uma relação causal direta: a falta de teste leva ao acúmulo de erros, o que leva a um aumento na entropia, o que leva a erros mais complexos e frequentes, afetando diretamente a correção e a confiabilidade dos algoritmos.

Falta de documentação e informação Silos

A documentação adequada é frequentemente ignorada ao desenvolver software, o que leva à fragmentação ou perda de conhecimento sobre como o sistema funciona e como apoiá -lo. Isso força os desenvolvedores a “apoiar” o sistema para fazer alterações, aumentando significativamente a probabilidade de mal -entendidos e modificações incorretas, o que leva diretamente a erros. Também complica seriamente a adaptação de novos desenvolvedores, pois informações críticas não estão disponíveis ou enganosas.

A entropia do programa ocorre devido à “falta de conhecimento” e “discrepâncias entre suposições gerais e o comportamento real do sistema existente”. Esta é uma observação organizacional mais profunda: a entropia se manifesta não apenas no nível do código, mas também no nível do conhecimento. Esses conhecimentos informais e implícitos são frágeis e são facilmente perdidos (por exemplo, ao deixar os membros da equipe), o que leva diretamente a erros ao tentar modificar, especialmente os novos membros da equipe, levando assim a integridade da lógica algorítmica, uma vez que suas principais suposições deixam de ser claras.

Métodos de desenvolvimento inconsistentes e perda de propriedade

O fator humano é um fator determinante significativo, geralmente subestimado, na entropia de software. Várias habilidades, codificação e expectativas de qualidade entre os desenvolvedores levam a inconsistências e desvios no código -fonte. A falta de processos padronizados para linhagem, revisões de código, testes e documentação exacerba esse problema. Além disso, um código pouco claro ou instável do código, quando vários comandos possuem parte do código ou nenhum possui, leva a negligenciar e aumentar em decaimento, o que leva à duplicação de componentes que desempenham a mesma função de maneiras diferentes, espalhando erros.

Isso mostra que a entropia não é apenas um problema técnico, mas também um sociotécnico, profundamente enraizado na dinâmica organizacional e no comportamento humano. A “inconsistência coletiva” que surge devido a práticas inconsistentes e posse fragmentada leva diretamente a inconsistências e defeitos, tornando o sistema imprevisível e difícil de controlar, o que afeta muito a integridade dos algoritmos.

Falações em cascata em sistemas interconectados

Os sistemas de software modernos geralmente são complexos e muito interconectados. Em tais sistemas, um alto grau de complexidade e componentes intimamente relacionados aumentam a probabilidade de falhas em cascata, quando a recusa de um componente causa uma reação em cadeia de falhas em outros. Esse fenômeno exacerba a influência de erros e o comportamento inadequado dos algoritmos, transformando problemas localizados em riscos sistêmicos. Os resultados dos algoritmos nesses sistemas se tornam muito vulneráveis a falhas que surgem longe de seu caminho direto de execução, o que leva a resultados incorretos generalizados.

A complexidade arquitetônica, a manifestação direta da entropia, pode transformar erros algorítmicos isolados em falhas de grande escala de escala, tornando o sistema geral não confiável e seus dados de saída não são confiáveis. Isso enfatiza a necessidade de estabilidade arquitetônica de conter a propagação de efeitos de entropia.

Um dos exemplos mais recentes é a parada bem conhecida dos aeroportos da América e da Europa devido ao aparecimento da tela de morte azul após atualizar o software antivírus em 2024, o resultado errôneo do algoritmo antivírus e o sistema operacional levou ao tráfego aéreo no mundo.

Exemplos práticos

Exemplo 1: Entropia em Unicode e Restrição de Byte

Vejamos um exemplo simples com um campo de texto, limitado por 32 bytes.

Cenário com ASCII (baixa entropia)

Se o campo aceitar apenas símbolos ASCII, cada símbolo pega 1 bytes. Assim, exatamente 32 caracteres são colocados no campo. Qualquer outro símbolo simplesmente não será aceito.

@startuml
Exemplo de título com ASCII (baixa entropia)
Usuário do ator
Participante “Textfield”

Usuário -> TextField: apresenta 32 símbolos ASCII
TextField -> TextField: verifica o comprimento (32 bytes)
Nota à direita
Tudo está bem.
Nota final
TextField -> Usuário: Aceps entrada
@enduml

Cenário com UTF-8 (alta entropia):

Agora, nosso programa de seus anos 80 cai em 2025. Quando o campo toma UTF-8, cada símbolo pode ocupar de 1 a 4 bytes. Se o usuário introduzir uma linha superior a 32 bytes, o sistema poderá cortá -la incorretamente. Por exemplo, o emoji ocupa 4 bytes. Se a poda ocorrer dentro do símbolo, obtemos um símbolo “quebrado”.

@startuml
Exemplo de título com UTF-8 (alta entropia)
Usuário do ator
Participante “Textfield”

Usuário -> TextField: apresenta “Hi” (37 byte)
TextField -> TextField: Corta a linha até 32 bytes
Nota à direita
De repente! Símbolo
Cortado por bytes.
Nota final
TextField -> Usuário: exibe “oi”
Nota esquerda
Símbolo incorreto.
Nota final
@enduml

Aqui a entropia se manifesta no fato de que a mesma operação de poda para diferentes dados de entrada leva a resultados imprevisíveis e incorretos.

Exemplo 2: Entropia no CSS e incompatibilidade dos navegadores

Mesmo em tecnologias aparentemente estáveis, como o CSS, a entropia pode ocorrer devido a diferentes interpretações dos padrões.

Imagine que o desenvolvedor aplicou o usuário eleito: nenhum; A todos os elementos para desativar a saída de texto.

navegador 10 (lógica antiga)

O navegador 10 faz uma exceção para os campos de entrada. Assim, apesar da bandeira, o usuário pode inserir dados.

@startuml
Navegador de título 10
Usuário do ator
Participante “Navegador 10” como navegador10

Usuário -> Browser10: Entrando na entrada
Browser10 -> navegador10: verifica o CSS
Nota à direita
-User-Elect: Nenhum;
Ignorado para entrada
Nota final
Navegador10 -> usuário: permite a entrada
@enduml

navegador 11 (nova lógica)

Os desenvolvedores do novo navegador decidiram seguir estritamente as especificações, aplicando a regra a todos os elementos sem exceção.

@startuml
Navegador de título 11
Usuário do ator
Participante “Navegador 11” como navegador11

Usuário -> Browser11: Inserindo a entrada
Navegador11 -> navegador11: verifica o CSS
Nota à direita
-User-Elect: Nenhum;
Aplicado a todos os elementos, incluindo entrada
Nota final
Navegador11 -> Usuário: se recusa a entrar
Nota esquerda
O usuário não pode fazer nada
tipo.
Nota final
@enduml

Este exemplo clássico de entropia – a mesma regra leva a diferentes resultados, dependendo do “sistema” (versão do navegador).

Exemplo 3: Entropia devido a um TK ambíguo

Uma tarefa técnica ambígua (TK) é outra fonte poderosa de entropia. Quando dois desenvolvedores, Bob e Alice, entendem o mesmo requisito de maneiras diferentes, isso leva a implementações incompatíveis.

TK: “Para implementar um gerador de números de Fibonacci. Para otimização, uma lista de números gerados deve ser armada dentro do gerador”.

Modelo mental de Bob (OOP com uma condição variável)
Bob se concentrou na frase “Lista … deve ser arrancada”. Ele implementou uma classe que armazena o mesmo estado (Self.Sensence) e a aumenta a cada chamada.

    def __init__(self):
        self.sequence = [0, 1]

    def generate(self, n):
        if n <= len(self.sequence):
            return self.sequence

        while len(self.sequence) < n:
            next_num = self.sequence[-1] + self.sequence[-2]
            self.sequence.append(next_num)

        return self.sequence

Modelo mental de Alice (abordagem funcional)

Alice se concentrou na frase "retorna a sequência". Ela escreveu uma função pura que retorna uma nova lista a cada vez, usando o cache apenas como otimização interna.

    sequence = [0, 1]
    if n <= 2:
        return sequence[:n]

    while len(sequence) < n:
        next_num = sequence[-1] + sequence[-2]
        sequence.append(next_num)

    return sequence

Quando Alice começa a usar o gerador Bob, ela espera que a geração (5) sempre retorne 5 números. Mas se antes disso Bob chamou Gereate (8) no mesmo objeto, Alice receberá 8 números.

Conclusão: entropia aqui está uma conseqüência dos modelos mentais. O estado mutável na implementação de Bob torna o sistema imprevisível para Alice, que aguarda o comportamento da função pura.

Entropia e multi -definição: a condição da raça e do avô

Na programação multi -fluxo, a entropia se manifesta especialmente. Vários fluxos são realizados simultaneamente e o procedimento para sua implementação é imprevisível. Isso pode levar à condição de corrida, quando o resultado depende de qual fluxo é o primeiro a acessar o recurso comum. O caso extremo é o avô quando dois ou mais fluxos estão esperando um pelo outro, e o programa congela.

Exemplo da solução de Dedlok:

O problema do Dedlok surge quando dois ou mais fluxo se bloqueiam, aguardando a liberação do recurso. A solução é estabelecer um procedimento único e fixo para aproveitar os recursos, por exemplo, bloqueá -los aumentando o ID. Isso exclui uma expectativa cíclica que impede o impasse.

@startuml
Solução de título: Procedimento de bloqueio unificado
Participante "Stream 1" como Thread1
Participante "Stream 2" como Thread2
Participante "como" como conta
Participante "Conta B" como conta

Thread1 -> Accounta: Blocks Conta A
Nota sobre o thread1
A regra segue:
ID do bloco
Nota final
Thread2 -> Accounta: esperando a conta A será libertado
Nota sobre Thread2
A regra segue:
Esperando por bloquear um
Nota final
Thread1 -> AccountB: Blocks Conta B
Thread1 -> Accounta: Frees Conta A
Thread1 -> AccountB: Liberações Pontuação B
Nota sobre o thread1
A transação está concluída
Nota final
Thread2 -> conta: bloqueia a conta a
Thread2 -> AccountB: Blocks Conta B
Nota sobre Thread2
A transação termina
Nota final
@enduml

Essa abordagem - bloqueio ordenado (pedidos de bloqueio) - é uma estratégia fundamental para prevenir os Deadlles em programação paralela.

Ótimo, vamos analisar como o estado mutável na abordagem OOP aumenta a entropia, usando o exemplo de desenho de tela e comparar isso com uma função pura.

Problema: Condição alterada e entropia

Quando o objeto tem um estado alterado, seu comportamento se torna imprevisível. O resultado de chamar o mesmo método depende não apenas de seus argumentos, mas também de toda a história da interação com esse objeto. Isso traz entropia para o sistema.

Considere as duas abordagens do retângulo que desenham tela: uma em um estilo OOP com uma condição variável, a outra em uma função funcional, com uma função pura.

1. Abordagem OOP: Classe com um estado variável
Aqui, criamos uma classe de cursor, que armazena seu estado interno, neste caso, cor. O método de desenho desenhará um retângulo usando esta condição.

  constructor(initialColor) {
    // Внутреннее состояние объекта, которое может меняться
    this.color = initialColor;
  }

  // Метод для изменения состояния
  setColor(newColor) {
    this.color = newColor;
  }

  // Метод с побочным эффектом: он использует внутреннее состояние
  draw(ctx, rect) {
    ctx.fillStyle = this.color;
    ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
  }
}

// Использование
const myCursor = new Cursor('red');
const rectA = { x: 10, y: 10, width: 50, height: 50 };
const rectB = { x: 70, y: 70, width: 50, height: 50 };

myCursor.draw(ctx, rectA); // Используется начальный цвет: red
myCursor.setColor('blue'); // Изменяем состояние курсора
myCursor.draw(ctx, rectB); // Используется новое состояние: blue

Diagrama UML da abordagem OOP:

Esse diagrama mostra claramente que a chamada do método de desenho fornece resultados diferentes, embora seus argumentos possam não mudar. Isso se deve a uma chamada setColor separada, que mudou o estado interno do objeto. Esta é uma manifestação clássica da entropia em um estado mutável.

title ООП-подход
actor "Программист" as Programmer
participant "Класс Cursor" as Cursor
participant "Canvas" as Canvas

Programmer -> Cursor: Создает new Cursor('red')
note left
  - Инициализирует состояние
    с цветом 'red'.
end note
Programmer -> Cursor: draw(ctx, rectA)
note right
  - Метод draw использует
    внутреннее состояние
    объекта (цвет).
end note
Cursor -> Canvas: Рисует 'red' прямоугольник
Programmer -> Cursor: setColor('blue')
note left
  - Изменяет внутреннее состояние!
  - Это побочный эффект.
end note
Programmer -> Cursor: draw(ctx, rectB)
note right
  - Тот же метод draw,
    но с другим результатом
    из-за измененного состояния.
end note
Cursor -> Canvas: Рисует 'blue' прямоугольник
@enduml

2. Abordagem funcional: função pura

Aqui usamos uma função pura. Sua tarefa é simplesmente desenhar um retângulo usando todos os dados necessários que são transmitidos a ele. Ela não tem condição, e seu desafio não afetará nada fora de suas fronteiras.

  // Функция принимает все необходимые данные как аргументы
  ctx.fillStyle = color;
  ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
}

// Использование
const rectA = { x: 10, y: 10, width: 50, height: 50 };
const rectB = { x: 70, y: 70, width: 50, height: 50 };

drawRectangle(ctx, rectA, 'red'); // Рисуем первый прямоугольник
drawRectangle(ctx, rectB, 'blue'); // Рисуем второй прямоугольник

Diagrama de uml de uma abordagem funcional:

Este diagrama mostra que a função Drawrectangle sempre recebe a cor externa. Seu comportamento depende completamente dos parâmetros de entrada, o que o torna limpo e com um baixo nível de entropia.

@startuml
Abordagem funcional do título
Ator "Programador" como programador
Participante "função \ n drecrectangle" como drawfunc
Participante "tela" como tela

Programador -> drawfunc: drawrewerctangle (ctx, reta, 'vermelho')
Nota à direita
- Ligue com argumentos:
- ctx
- Recta (coordenadas)
- 'vermelho' (cor)
- A função não tem condição.
Nota final

DrawFunc -> Canvas: inundações com a cor 'vermelha'
Programador -> drawfunc: dreatrewerctangle (ctx, retb, 'azul')
Nota à direita
- Ligue com novos argumentos:
- ctx
- Retb (coordenadas)
- 'azul' (cor)
Nota final
DrawFunc -> Canvas: inundações com a cor 'azul'
@enduml

Em um exemplo com uma função pura, o comportamento é completamente previsível, pois a função não tem condição. Todas as informações para o trabalho são transmitidas por meio de argumentos, o que a torna isolada e segura. Em uma abordagem OOP com um estado variável para o comportamento do método de desenho, toda a história da interação com o objeto pode afetar, o que introduz entropia e torna o código menos confiável.

Design e arquitetura modulares: isolamento, testabilidade e re -use

A divisão de sistemas complexos em módulos menores, independentes e auto -suficientes simplifica o design, desenvolvimento, teste e manutenção. Cada módulo processa certas funcionalidades e interage através de interfaces claramente definidas, reduzindo a interdependência e contribuindo para a separação de responsabilidade. Essa abordagem melhora a legibilidade, simplifica a manutenção, facilita o desenvolvimento paralelo e simplifica testes e depuração, isolando problemas. É fundamental que isso reduz o "raio da derrota" de erros, segurando defeitos em módulos separados e impedindo falhas em cascata. A arquitetura do microsserviço é uma poderosa realização da modalidade.

A modularidade não é apenas uma maneira de organizar o código, mas também uma abordagem fundamental para conter defeitos e aumentar a estabilidade. Limitando o impacto do erro em um módulo, a modalidade aumenta a estabilidade geral do sistema para decaimento de entropia, garantindo que um ponto de recusa não comprometa a correção de todo o aplicativo. Isso permite que as equipes se concentrem em partes menores e mais controladas do sistema, o que leva a testes mais completos e erros de detecção e correção mais rápidos.

Práticas de código puro: beijo, seca e princípios sólidos para confiabilidade

Beijo (mantenha -o simples, estúpido):
Essa filosofia de design significa simplicidade e clareza, evitando ativamente a complexidade desnecessária. Um código simples é inerentemente mais fácil de ler, entender e modificar, o que leva diretamente a uma diminuição em uma tendência a erros e melhorar o suporte. A complexidade é claramente definida como um ambiente de nutrientes para erros.

O KISS não é apenas uma preferência estética, mas uma escolha deliberada de design, que reduz a superfície do ataque por erros e torna o código mais resistente a mudanças futuras, mantendo assim a correção e a previsibilidade dos algoritmos. Esta é uma medida proativa contra entropia em um nível detalhado de código.

Seco (não se repita):
O princípio seco visa reduzir a repetição de informações e duplicação de código, substituindo -a por abstrações ou usando a normalização dos dados. Sua posição principal é que "cada fragmento de conhecimento deve ter uma representação única, inequívoca e autoritária no sistema". Essa abordagem elimina a redundância, que, por sua vez, reduz as inconsistências e evita a propagação de erros ou sua correção inconsistente em várias cópias da lógica duplicada. Ele também simplifica o suporte e a depuração da base de código.

A duplicação do código leva a alterações inconsistentes, o que, por sua vez, leva a erros. O seco impede isso, fornecendo uma única fonte de verdade para lógica e dados, que contribuem diretamente para a correção dos algoritmos, garantindo que a lógica geral se comporte de maneira uniforme e previsível em todo o sistema, impedindo que erros finos e difíceis de inserir.

sólido

princípios

Este acrônimo mnemônico apresenta cinco princípios fundamentais de design (responsabilidade unificada, abertura/proximidade, substituição de liskin, separação de interfaces, inversões de dependências) que são cruciais para a criação de projetos orientados a objetos claros, flexíveis e solidários. A adesão a entidades sólidas de software se torna mais fácil de suportar e adaptar, o que leva a um número menor de erros e ciclos de desenvolvimento mais rápidos. Eles conseguem isso simplificando o Serviço (SRP), garantindo as funções de adição escalável sem modificação (OCP), garantindo consistência comportamental (LSP), minimizando a coerência (ISP) e aumentando a flexibilidade devido à abstração (DIP).

Os princípios sólidos fornecem uma abordagem holística da integridade estrutural, que torna o sistema em essência mais resistente aos efeitos de acrobacias das mudanças. Promovendo modularidade, separação e responsabilidades claras, eles impedem erros em cascata e mantêm a correção dos algoritmos, mesmo quando o sistema é continuamente evolução, atuando como medidas fundamentais para combater a entropia.

Design de entropia e domínio (DDD)

O design orientado ao domínio (DDD) não é apenas uma filosofia, mas uma metodologia completa que oferece padrões específicos para dividir a aplicação em domínios, o que permite controlar efetivamente a complexidade e combater a entropia. O DDD ajuda a transformar um sistema caótico em um conjunto de componentes previsíveis e isolados.

Padrões de gangue de quatro design como um único aparelho conceitual

O livro "Padrões de design: elementos do software reutilizável orientado a objetos" (1994), escrito por uma "gangue de quatro" (GOF), ofereceu um conjunto de soluções comprovadas para problemas típicos. Esses padrões são excelentes ferramentas para combater a entropia, pois criam sistemas estruturados, previsíveis e controlados.

Um dos principais efeitos dos padrões é a criação de um único aparelho conceitual. Quando o desenvolvedor em uma equipe fala sobre a "fábrica" ou "solitária", seus colegas entendem imediatamente de que tipo de código é que estamos falando. Isso reduz significativamente a entropia na comunicação, porque:

A ambiguidade diminui: os padrões têm nomes e descrições claras, o que exclui diferentes interpretações, como no exemplo de Bob e Alice.

Acelera o intervalo: os novos membros da equipe são derramados mais rapidamente no projeto, pois não precisam adivinhar a lógica atrás de estruturas complexas.

A refatoração é facilitada: se você precisar alterar a parte do sistema construído de acordo com o padrão, o desenvolvedor já sabe como é organizado e quais peças podem ser modificadas com segurança.

Exemplos de padrões de GOF e sua influência na entropia:

Padrão "Estratégia": permite encapsular vários algoritmos em classes individuais e torná -los intercambiáveis. Isso reduz a entropia, pois permite alterar o comportamento do sistema sem alterar seu código principal.

Padrão "comando" (comando): inkapsules o método do método para o objeto. Isso permite que você adie a execução, coloque os comandos na fila ou os cancele. O padrão reduz a entropia, pois separa o remetente da equipe de seu destinatário, tornando -os independentes.

Padrão de observador (observador): determina a dependência do "um para muitos", no qual uma alteração no estado de um objeto notifica automaticamente todos os dependentes. Isso ajuda a controlar os efeitos colaterais, tornando -os óbvios e previsíveis, e não caóticos e ocultos.

Padrão "Método da Fábrica": define a interface para criar objetos, mas permite que as subclasses decidam qual classe instituir. Isso reduz a entropia, pois permite criar objetos com flexibilidade sem a necessidade de conhecer classes específicas, reduzindo a conexão.

Esses padrões ajudam os programadores a criar sistemas mais previsíveis, testados e controlados, reduzindo assim a entropia, o que ocorre inevitavelmente em projetos complexos.

Padrões -chave DDD para controlar a entropia

Contextos limitados: esse padrão é a fundação DDD. Ele se oferece para dividir um grande sistema em peças pequenas e autônomas. Cada contexto tem seu próprio modelo, um dicionário de termos (idioma onipresente) e lógica. Isso cria limites estritos que impedem a propagação de mudanças e efeitos colaterais. A mudança em um contexto limitado, por exemplo, no "contexto das ordens", não afetará o "contexto de entrega".

Agregados (agregados): A unidade é um cluster de objetos relacionados (por exemplo, "ordem", "linhas da ordem"), que é considerada como um todo. A unidade possui um objeto raiz (raiz agregada), que é o único ponto de entrada para todas as alterações. Isso fornece consistência e garante que o estado da unidade sempre permaneça integral. Ao alterar a unidade apenas através de seu objeto raiz, controlamos como e quando há uma alteração na condição, o que reduz significativamente a entropia.

Serviços de domínio Serviços: Para operações que não pertencem a nenhum objeto específico da área de assunto (por exemplo, a transferência de dinheiro entre contas), o DDD propõe usar os serviços de domínio. Eles coordenam as ações entre várias unidades ou objetos, mas não mantêm a condição. Isso torna a lógica mais transparente e previsível.

Os eventos da área de assunto (eventos de domínio): em vez de métodos de chamada direta de diferentes contextos, o DDD oferece para usar eventos. Quando algo importante acontece em um contexto, ele "publica" o evento. Outros contextos podem se inscrever neste evento e responder a ele. Isso cria uma conexão fraca entre os componentes, o que torna o sistema mais escalável e resistente a alterações.

O DDD ajuda a controlar a entropia, criando limites claros, regras estritas e componentes isolados. Isso transforma um sistema complexo e confuso em um conjunto de partes independentes e controladas, cada uma das quais tem sua própria "lei" e comportamento previsível.

Documentação complexa e animada

Manter documentação detalhada e relevante sobre alterações de código, soluções de design, diagramas arquitetônicos e manuais do usuário é de suma importância. Essa "documentação ao vivo" ajuda os desenvolvedores a entender os meandros do sistema, rastrear alterações e comemoradamente fazer modificações futuras ou corrigir erros. Reduz significativamente o tempo gasto na “re -abertura” ou no design reverso do sistema, que são fontes comuns de erros.

A entropia do programa ocorre devido à "falta de conhecimento" e "discrepâncias entre suposições gerais e o comportamento real do sistema existente". A documentação atua não apenas como um guia, mas como

O mecanismo crítico para preservar o conhecimento, que luta diretamente com a "entropia do conhecimento". Ao tornar o conhecimento implícito explícito e acessível, reduz os mal -entendidos e a probabilidade de cometer erros devido a suposições incorretas sobre o comportamento de algoritmos ou interações do sistema, protegendo assim a correção funcional.

Teste rigoroso e garantia de qualidade contínua

Testes automatizados: testes modulares, de integração, sistema e regressão
O teste automatizado é uma ferramenta indispensável para amolecer a entropia do software e prevenir erros. Ele permite a detecção precoce de problemas, garantindo que as alterações de código não violem a funcionalidade existente e fornecem feedback rápido e consistente. Os tipos de chave incluem testes modulares (para componentes isolados), testes de integração (para interações entre módulos), testes do sistema (para um sistema integrado completo) e testes de regressão (para garantir que novas alterações não levem à aparência repetida de erros antigos). O teste automatizado reduz significativamente o fator humano e aumenta a confiabilidade.

O teste automatizado é a principal proteção contra o acúmulo de defeitos ocultos. Ele "muda" ativamente a descoberta de erros para a esquerda no ciclo de desenvolvimento, o que significa que os problemas são encontrados quando sua correção é a mais barata e mais simples, impedindo sua contribuição para o efeito do coma de neve da entropia. Isso afeta diretamente a correção dos algoritmos, constantemente verificando o comportamento esperado em vários níveis de detalhe.

Desenvolvimento através do teste (TDD): Mudar para a esquerda na detecção de erros

O desenvolvimento através do teste (TDD) é um processo de desenvolvimento de software, que inclui a gravação de testes para o código antes de escrever o código em si. Esse ciclo iterativo "refactorar vermelho-verde" promove um feedback rápido, permitindo a detecção precoce de erros e reduzindo significativamente o risco de problemas complexos em estágios posteriores de desenvolvimento. Foi demonstrado que o TDD leva a um número menor de erros e à qualidade ideal do código, coordenando bem a filosofia da seca (não se repete). Estudos empíricos da IBM e da Microsoft mostram que o TDD pode reduzir a densidade de erro a ser lançada em impressionantes 40-90%. Exemplos de teste também servem como documentação ao vivo.

O TDD atua como controle proativo da qualidade, construído diretamente no processo de desenvolvimento. Forçando os desenvolvedores a determinar o comportamento esperado antes da implementação, minimiza a introdução de erros lógicos e garante que o código seja criado propositadamente para cumprir os requisitos, melhorando diretamente a correção e a previsibilidade dos algoritmos desde o início.

Integração e entrega contínuas (IC/CD): Feedback inicial e liberações estáveis
As práticas de CI/CD são fundamentais para o desenvolvimento moderno de software, ajudando a identificar erros nos estágios iniciais, acelerar o desenvolvimento e garantir o processo de implantação ininterrupto. A integração frequente de pequenos pacotes de código no repositório central permite a detecção precoce de erros e a melhoria contínua da qualidade do código por meio de conjuntos e testes automatizados. Esse processo fornece um feedback rápido, permitindo que os desenvolvedores eliminem de maneira rápida e eficaz os problemas e também aumente significativamente a estabilidade do código, impedindo o acúmulo de código não verificado ou instável.

Os transportadores de CI/CD funcionam como um mecanismo contínuo para reduzir a entropia. Ao automatizar a integração e o teste, eles impedem o acúmulo de problemas de integração, fornecem uma condição constantemente em desdobramento e fornecem visibilidade imediata de regressão. Essa abordagem sistemática e automatizada neutraliza diretamente o distúrbio feito por alterações contínuas, mantendo a estabilidade dos algoritmos e impedindo a propagação de erros em todo o sistema.

Gerenciamento sistemático da dívida técnica

REFATORIA INCRECIONAL: Melhoria estratégica de código

A refatoração é o processo de reestruturação do código existente para melhorar sua estrutura interna sem alterar seu comportamento externo. Esse é um meio direto de combater o software apodrecendo e reduzindo a complexidade. Embora a refatoração seja geralmente considerada uma maneira de reduzir o número de erros, é importante admitir que algumas refraturas podem contribuir com inauguração novos erros, o que requer testes rígidos. No entanto, os estudos geralmente confirmam que o código refratado está menos sujeito a erros do que o não aceito. Increting A refatoração, na qual o gerenciamento da dívida é integrada ao atual processo de desenvolvimento e não é adiada, é crucial para impedir o acúmulo exponencial da dívida técnica.

A refatoração é uma ação deliberada para reduzir a entropia, reestruturação de código proativo para torná -la mais resistente a alterações, reduzindo assim a probabilidade de erros futuros e melhorar a clareza dos algoritmos. Transforma incêndios reativos com extinção no gerenciamento proativo da saúde estrutural.

Backlogs da dívida técnica: priorização e distribuição de recursos

A manutenção de um Bablog atual da dívida técnica é uma prática crítica para o gerenciamento sistemático e a eliminação da dívida técnica. Este backlog serve como um registro abrangente de elementos identificados de serviço técnico e áreas que exigem melhorias, garantindo que esses problemas não sejam negligenciados. Ele permite que os gerentes de projeto priorizem os elementos da dívida com base em sua seriedade de influência e riscos potenciais. A integração do Bablog durante o projeto garante que a refatoração, a correção de erros e a limpeza de código sejam partes regulares do gerenciamento diário do projeto, reduzindo os custos de pagamento de longo prazo.

O baclog da dívida técnica transforma um problema abstrato e crescente em um conjunto de tarefas controlado e eficaz. Essa abordagem sistemática permite que as organizações adotem compromissos razoáveis entre o desenvolvimento de novas funções e investimentos em qualidade, impedindo a acumulação de dívida discreta, o que pode levar a erros críticos ou degradação da produtividade do algoritmo. Ele fornece visibilidade e controle sobre o poder de entropia da chave.

Análise de código estático e dinâmico: identificação proativa de problemas

Análise estática

Essa técnica inclui uma análise do código -fonte sem sua implementação para identificar problemas como erros, cheiros de código, vulnerabilidade de segurança e padrões de codificação prejudicados. Ele serve como a “primeira linha de proteção”, identificando problemas nos estágios iniciais do ciclo de desenvolvimento, melhorando a qualidade geral do código e reduzindo a dívida técnica, identificando modelos problemáticos antes que eles apareçam como erros durante a execução.

A análise estática atua como uma "polícia de qualidade de código automatizada". Identificando problemas em potencial (incluindo aqueles que afetam a lógica algorítmica) antes de executar, evita sua manifestação na forma de erros ou desvantagens arquitetônicas. Este é um método escalável de garantir padrões de codificação e identificar erros comuns que contribuem para a entropia do software.

Análise dinâmica

Este método avalia o comportamento do software durante a execução, fornecendo informações valiosas sobre problemas que se manifestam apenas durante a execução. Excelentemente descobre erros durante a execução, como vazamentos de memória, a condição da raça e a exclusão do ponteiro zero, bem como locais estreitos no desempenho e vulnerabilidade da segurança.

A análise dinâmica é fundamental para identificar desvantagens comportamentais durante a execução, que não pode ser detectada por análise estática. A combinação de análise estática e dinâmica garante uma idéia abrangente da estrutura e comportamento do código, permitindo que as equipes identifiquem defeitos antes de se transformarem em problemas sérios.

Monitorando a produção e o escritório de incidentes

APM (Monitoramento de desempenho do aplicativo):
As ferramentas APM foram projetadas para monitorar e otimizar o desempenho dos aplicativos. Eles ajudam a identificar e diagnosticar problemas complexos de desempenho, além de detectar as causas raiz dos erros, reduzindo assim a perda de renda do tempo de inatividade e da degradação. Os sistemas APM monitoram várias métricas, como tempo de resposta, uso de recursos e frequência de erros, fornecendo informações em tempo real, o que permite resolver proativamente os problemas antes que eles afetem os usuários.

As ferramentas da APM criticam soluções proativas para problemas e manutenção dos níveis de serviço. Eles fornecem uma visibilidade profunda no ambiente de produção, permitindo que as equipes identifiquem e eliminem rapidamente problemas que podem afetar os algoritmos corretos ou causar erros, minimizando assim o tempo de inatividade e melhorando a experiência do usuário.

Observabilidade (logs, métricas, rastreio):

A observabilidade refere -se à capacidade de analisar e medir os estados internos dos sistemas com base em seus dados de saída e interações entre ativos. Três pilares principais de observabilidade são métricas (dados quantitativos sobre produtividade e uso de recursos), logs (registros cronológicos detalhados de eventos) e rastreamento (rastreando o fluxo de solicitações através de componentes do sistema). Juntos, eles ajudam a identificar e resolver problemas, fornecendo uma compreensão abrangente do comportamento do sistema. A observabilidade vai além do monitoramento tradicional, ajudando a entender "desconhecido desconhecido" e melhorando o tempo da aplicação livre de aplicativos.

A observabilidade permite que as equipes investigem flexivelmente o que está acontecendo e determine rapidamente a causa raiz dos problemas que podem não ter previsto. Isso fornece uma compreensão mais profunda, flexível e proativa do comportamento do sistema, permitindo que as equipes identifiquem rapidamente e eliminem problemas imprevistos e mantenham a alta acessibilidade dos aplicativos.

Análise da causa raiz (RCA)

A análise das causas radiculares (RCA) é um processo estruturado com base em dados que revelam as causas fundamentais de problemas em sistemas ou processos, permitindo que as organizações implementem soluções eficazes e de longo prazo, e não apenas elimine os sintomas. Inclui a definição do problema, coleta e análise dos dados relevantes (por exemplo, métricas, logs, escalas temporárias), determinação de fatores causais e relacionados usando ferramentas como "5 por que" e diagramas de Ishikawa, bem como o desenvolvimento e implementação de ações corretivas. A RCA é crucial para impedir a re -ocorrência de problemas e treinamento em incidentes.

A RCA é crucial para a prevenção a longo prazo de problemas e treinamento em incidentes. Identificando e eliminando sistematicamente as principais causas, e não apenas os sintomas, as organizações podem impedir a re -ocorrência de erros e falhas de algoritmos, reduzindo assim o sistema geral do sistema e aumentando sua confiabilidade.

Metodologias flexíveis e práticas de equipe

Gerenciamento de erros no Agile:

No ambiente ágil, o gerenciamento de erros é extremamente importante e é recomendável alocar o tempo em sprints para corrigi -los. Os erros devem ser registrados em um único produto do produto e associados ao histórico correspondente para facilitar a análise de causas radiculares e melhorar o código nas sprints subsequentes. As equipes devem se esforçar para corrigir os erros o mais rápido possível, de preferência no sprint atual, a fim de impedir seu acúmulo. A coleta de estatísticas de erros (o número de resolvidos, o número de horas registradas e as horas em correção) ajuda a ter uma idéia da qualidade do código e melhorar os processos.

Isso enfatiza a importância de correções imediatas, análise de causas radiculares e melhora contínua. As metodologias flexíveis fornecem uma estrutura para o controle proativo dos erros, impedindo sua contribuição para a entropia do sistema e mantendo a correção dos algoritmos por verificação e adaptação constantes.

DevOps

Práticas

As práticas do DevOps ajudam a reduzir os defeitos do software e melhorar a qualidade através de várias abordagens importantes. Eles incluem o desenvolvimento de uma cultura de cooperação e comunicação inconfundível, a adoção de integração e entrega contínuas (IC/CD), a configuração de testes automatizados, focando a atenção na observabilidade e métricas, evitando trabalho artesanal, incluindo segurança nos estágios iniciais do ciclo de desenvolvimento e treinamento em incidentes. Essas práticas reduzem o número de erros, melhoram a qualidade e contribuem para melhorias constantes.

O DevOps contribui para a melhoria contínua e a redução da entropia através da automação, feedback rápido e uma cultura de responsabilidade geral. Integrando os processos de desenvolvimento e operação, o DevOps cria um ambiente no qual os problemas são detectados e eliminados rapidamente, impedindo sua acumulação e degradação de sistemas, que suporta diretamente a integridade dos algoritmos.

Conclusão

A entropia do programa é uma força inevitável que se esforça constantemente para a degradação de sistemas de software, especialmente no contexto da correção de algoritmos e erros. Isso não é apenas o envelhecimento físico, mas uma interação dinâmica entre o código, seu ambiente e fatores humanos que constantemente fazem uma bagunça. As principais forças motrizes desse decaimento incluem crescente complexidade, acúmulo de dívida técnica, documentação inadequada, alterações em ambientes externos constantemente e métodos de desenvolvimento inconsistentes. Esses fatores levam diretamente a resultados incorretos do trabalho de algoritmos, a perda de previsibilidade e um aumento no número de erros que podem se espalhar em cascata pelos sistemas interconectados.

A luta contra a entropia de software requer uma abordagem multifacetada, contínua e proativa. Não basta apenas corrigir erros à medida que ocorrem; É necessário eliminar sistematicamente os principais motivos que os geram. A adoção dos princípios do design modular, código limpo (beijo, seco, sólido) e documentação complexa é fundamental para a criação de sistemas estáveis, que são essencialmente menos suscetíveis à entropia. Testes automatizados rigorosos, desenvolvimento por meio de testes (TDD) e integração/entrega contínua (IC/CD) atuam como mecanismos críticos da detecção e prevenção precoce de defeitos, constantemente verificando e estabilizando a base de código.

Além disso, o gerenciamento sistemático da dívida técnica por meio de refatoração incidental e bafflogistas da dívida técnica, bem como o uso de ferramentas estáticas e dinâmicas de análise de código, permite que as organizações identifiquem e eliminem ativamente as áreas problemáticas antes de levarem a falhas críticas. Finalmente, o monitoramento confiável da produção com a ajuda de ferramentas APM e plataformas de observabilidade, em combinação com uma análise disciplinada das causas radiculares e práticas flexíveis da equipe, garante uma rápida resposta a problemas emergentes e cria um ciclo de melhoria contínua.

Por fim, garantindo a integridade dos algoritmos e minimizando erros nas condições de entropia de software - esse não é um esforço único, mas uma obrigação constante de manter a ordem em um ambiente dinâmico e em constante mudança. Aplicando essas estratégias, as organizações podem aumentar significativamente a confiabilidade, previsibilidade e durabilidade de seus sistemas de software, garantindo que os algoritmos funcionarão conforme o planejado, mesmo à medida que se evoluem.

Diagramas de bloqueio na prática sem formalina

O diagrama de blocos é uma ferramenta visual que ajuda a transformar um algoritmo complexo em uma sequência de ações compreensíveis e estruturadas. Da programação ao gerenciamento de processos de negócios, eles servem como uma linguagem universal para visualização, análise e otimização dos sistemas mais complexos.

Imagine um mapa onde, em vez de estradas, é lógica e, em vez de cidades – ações. Esta é um diagrama de blocos-uma ferramenta indispensável para navegação nos processos mais confusos.

Exemplo 1: Esquema de lançamento de jogo simplificado
Para entender o princípio do trabalho, vamos apresentar um simples esquema de lançamento de jogo.

Esse esquema mostra o script perfeito quando tudo acontece sem falhas. Mas na vida real, tudo é muito mais complicado.

Exemplo 2: Esquema expandido para iniciar o jogo com carregamento de dados
Os jogos modernos geralmente exigem conexão à Internet para baixar dados, salvamento ou configurações do usuário. Vamos adicionar essas etapas ao nosso esquema.

Esse esquema já é mais realista, mas o que acontecerá se algo der errado?

Como foi: um jogo que “quebrou” com a perda da Internet

No início do projeto, os desenvolvedores não puderam levar em consideração todos os cenários possíveis. Por exemplo, eles se concentraram na lógica principal do jogo e não pensaram no que aconteceria se o jogador tivesse uma conexão com a Internet.

Em tal situação, o diagrama de blocos de seu código ficaria assim:

Nesse caso, em vez de emitir um erro ou fechar corretamente, o jogo congelou na fase de espera por dados que ela não recebeu devido à falta de uma conexão. Isso levou à “tela preta” e congelando o aplicativo.

Como se tornou: correção nas reclamações de usuários

Após inúmeras reclamações dos usuários sobre pairando, a equipe do desenvolvedor percebeu que precisávamos corrigir o erro. Eles fizeram alterações no código adicionando uma unidade de processamento de erros que permite que o aplicativo responda corretamente à falta de conexão.

É assim que o diagrama de blocos corrigido se parece, onde ambos os cenários são levados em consideração:

Graças a essa abordagem, o jogo agora informa corretamente o usuário sobre o problema e, em alguns casos, ele pode até ir para o modo offline, permitindo que você continue o jogo. Este é um bom exemplo de por que os diagramas de blocos são tão importantes : eles fazem o desenvolvedor pensar não apenas sobre a maneira ideal de execução, mas também sobre todas as falhas possíveis, tornando o produto final muito mais estável e confiável.

comportamento incerto

Pendurado e erros são apenas um exemplos de comportamento imprevisível do programa. Na programação, existe um conceito de comportamento incerto (comportamento indefinido) – Esta é uma situação em que o padrão do idioma não descreve como o programa deve se comportar em um determinado caso.

Isso pode levar a qualquer coisa: do “lixo” aleatório na retirada ao fracasso do programa ou mesmo à séria vulnerabilidade de segurança. O comportamento indefinido geralmente ocorre ao trabalhar com memória, por exemplo, com linhas na linguagem de C.

Um exemplo do idioma c:

Imagine que o desenvolvedor copiou a linha para o buffer, mas esqueceu de adicionar ao final o símbolo zero (`\ 0`) , que marca o final da linha.

É assim que o código se parece:

#include 

int main() {
char buffer[5];
char* my_string = "hello";

memcpy(buffer, my_string, 5);

printf("%s\n", buffer);
return 0;
}

Resultado esperado: “Olá”
O resultado real é imprevisível.

Por que isso está acontecendo? A função `printf` com o especificador`%s` espera que a linha termine com um símbolo zero. Se ele não estiver, ela continuará lendo a memória fora do buffer destacado.

Aqui está o diagrama de blocos deste processo com dois resultados possíveis:

Este é um exemplo claro de por que os diagramas de blocos são tão importantes: eles fazem o desenvolvedor pensar não apenas sobre a maneira ideal de execução, mas também sobre todas as falhas possíveis, incluindo problemas de baixo nível, tornando o produto final muito mais estável e confiável.

LLM Fine-Tune

Atualmente, todos os provedores populares de serviços LLM usam ajuste fino usando arquivos JSONL, que descrevem as entradas e saídas do modelo, com pequenas variações, por exemplo, para Gemini, OpenAI, o formato é um pouco diferente.

Após o download de um arquivo JSONL especialmente formado, o processo de especialização do modelo LLM no conjunto de dados especificado começa, para todos os provedores de LLM bem conhecidos atuais, este serviço é pago.

Para ajustar uma máquina local usando Ollama, recomendo confiar em um vídeo detalhado da tecnologia de canal do YouTube com a maneira mais fácil de ajustar um LLM e nós com Alloma:
https://www.youtube.com/watch?v=pTaSDVz0gok

Um exemplo de um laptop Jupyter com a preparação do conjunto de dados JSONL a partir de exportações de todas as mensagens do Telegram e o lançamento do processo de ajuste fino local está disponível aqui:
https://github.com/demensdeum/llm-train-example