Translate

quinta-feira, 5 de maio de 2022

DSA para Programadores COBOL Padawan

 

Bellacosa Mainframe apresenta DSA para programadores

☕ Um Café no Bellacosa Mainframe

DSA para Programadores COBOL Padawan

Você Não Precisa Decorar 500 Problemas do LeetCode. Precisa Aprender a Reconhecer Padrões.

"Todo programador iniciante acredita que grandes desenvolvedores conhecem milhares de algoritmos. Depois de alguns anos de experiência, descobre que eles conhecem apenas algumas dezenas de padrões... e sabem exatamente quando utilizá-los."


Existe uma pergunta que aparece frequentemente entre jovens programadores COBOL que desejam migrar para o universo moderno da Engenharia de Software:

"Preciso aprender LeetCode para conseguir boas oportunidades?"

Minha resposta normalmente surpreende.

Não.

Você precisa aprender como pensar.

LeetCode é uma academia.

DSA (Data Structures and Algorithms) é aprender anatomia.

Um fisiculturista pode decorar todos os exercícios da academia.

Um médico entende músculos, ossos, tendões e articulações.

Quem entende anatomia consegue criar novos exercícios.

Quem entende DSA consegue resolver problemas que nunca viu antes.

Essa é exatamente a diferença entre decorar soluções e compreender padrões.

E essa diferença vale tanto para um desenvolvedor Java quanto para um veterano de COBOL com trinta anos de experiência em sistemas bancários.


O Programador COBOL Já Conhece DSA (Mesmo Sem Saber)

Essa talvez seja a maior surpresa.

Muitos profissionais de Mainframe acreditam que DSA é uma invenção recente.

Não é.

Na verdade, você trabalha com isso há décadas.

Veja alguns exemplos.

Quando você faz uma leitura sequencial de um arquivo VSAM...

...está explorando uma estrutura de dados.

Quando faz um SEARCH ALL...

...está utilizando Binary Search.

Quando usa tabelas OCCURS...

...está manipulando Arrays.

Quando organiza registros por chave...

...está trabalhando com algoritmos de ordenação.

Quando utiliza um índice alternativo no VSAM...

...está explorando conceitos semelhantes às árvores de busca.

O que mudou foi apenas a nomenclatura.


O Grande Erro de Quem Estuda LeetCode

Imagine que alguém queira aprender COBOL.

Então começa resolvendo programas aleatórios.

Um dia faz folha de pagamento.

No outro faz cálculo de imposto.

Depois processamento de boletos.

Na semana seguinte faz conciliação bancária.

Será que ele aprenderá COBOL?

Provavelmente não.

Porque cada programa utiliza conceitos diferentes.

Com DSA acontece exatamente o mesmo.

Resolver problemas aleatórios é uma forma extremamente lenta de aprender.

Muito melhor é dominar um padrão de cada vez.

Quando você aprende Sliding Window...

...de repente resolve cinquenta problemas diferentes.

Quando entende HashMap...

...mais cinquenta deixam de parecer difíceis.

É um efeito multiplicador.


Pensando Como um Analista de Sistemas

Um analista experiente nunca começa programando.

Ele começa fazendo perguntas.

Da mesma forma, um bom solucionador de problemas faz um diagnóstico antes de escrever uma linha de código.

Seu raciocínio deveria seguir algo parecido com isto:

Que tipo de dado eu possuo?

↓

Qual estrutura representa melhor esses dados?

↓

Existe um padrão conhecido?

↓

Qual algoritmo resolve isso?

↓

Quanto custa em tempo?

↓

Quanto custa em memória?

Perceba que programação é apenas o último passo.

O verdadeiro trabalho acontece antes.


Arrays: O Arquivo Sequencial da Programação

Se existe uma estrutura que todo programador COBOL domina intuitivamente, é o Array.

Em COBOL:

01 CLIENTES.
   05 CLIENTE OCCURS 1000 TIMES.
      10 NOME PIC X(30).

Isso é um Array.

Na maioria das linguagens modernas:

clientes[1000]

É exatamente o mesmo conceito.

O interessante é que vários algoritmos famosos trabalham exclusivamente sobre Arrays.

Entre eles:

  • Prefix Sum

  • Sliding Window

  • Kadane

  • Binary Search

Cada um resolve um tipo específico de problema.


Prefix Sum: Quando Somar Milhões de Registros Precisa Ser Rápido

Imagine um banco.

Existe um histórico diário de saldo.

O gerente pergunta:

"Qual foi a movimentação entre os dias 500 e 1800?"

A solução ingênua seria somar tudo novamente.

Mas isso custa:

O(n)

Prefix Sum cria uma tabela acumulada.

Depois disso qualquer consulta vira praticamente instantânea.

Essa ideia aparece em:

  • Data Warehouses

  • BI

  • Analytics

  • Processamento Financeiro

  • Mainframe Batch

Embora muitos profissionais não percebam, diversas rotinas históricas de fechamento utilizam exatamente esse princípio.


Sliding Window: Não Recalcule o Que Você Já Sabe

Imagine um programa que precisa descobrir os três maiores dias consecutivos de vendas.

Um iniciante faz isto:

Soma dia 1

Soma dia 2

Soma dia 3

Depois recomeça tudo.

Um desenvolvedor experiente pensa diferente.

"Já conheço dois dos três valores."

Então remove apenas o elemento que saiu da janela e adiciona o próximo.

É como acompanhar uma esteira rolante.

Você não desmonta a esteira inteira para observar o próximo objeto.

Apenas acompanha seu movimento.

Esse padrão reduz muitos problemas de O(n²) para O(n).


Binary Search: Muito Além de Procurar

Todo mundo conhece Binary Search como uma busca em listas ordenadas.

Mas existe um detalhe interessante.

Hoje ele é muito mais utilizado para responder perguntas como:

"Qual é o menor valor possível?"

"Qual é a menor capacidade de armazenamento?"

"Qual é a menor velocidade aceitável?"

Sempre que existe uma resposta monotônica, Binary Search pode aparecer.

É por isso que ele continua sendo um dos algoritmos preferidos em entrevistas.


Strings: O Mundo dos Textos

Mainframes trabalham intensamente com texto.

CPF.

Nome.

Código de Agência.

Número da Conta.

Mensagens.

Arquivos CNAB.

Tudo isso são Strings.

Existem alguns padrões clássicos.

Two Pointers

Muito útil para:

  • remover espaços

  • comparar extremos

  • detectar palíndromos

É simples.

Dois ponteiros caminham em velocidades diferentes ou em sentidos opostos.


KMP

Imagine procurar uma palavra dentro de um documento de centenas de megabytes.

Sem estratégia...

...você volta inúmeras vezes ao início.

KMP evita repetir trabalho.

Ele aprende durante a própria busca.

É um excelente exemplo de algoritmo inteligente.


HashMap: A Memória Instantânea

HashMap talvez seja a estrutura que mais transforma problemas difíceis em problemas simples.

Imagine a pergunta:

"Este CPF já apareceu?"

Sem HashMap:

Procure tudo novamente.

Com HashMap:

Consulte diretamente.

É praticamente um índice em memória.

Quem trabalhou com índices DB2 entende rapidamente essa ideia.

Não percorremos a tabela inteira.

Consultamos uma estrutura otimizada.


Pilhas (Stacks): A Forma Natural de Resolver Alguns Problemas

Uma Stack segue a regra:

Last In

First Out

Ou seja:

O último que entra é o primeiro que sai.

Pense numa pilha de JCLs impressos.

O último colocado em cima será retirado primeiro.

Stacks aparecem em:

  • compiladores

  • interpretadores

  • validação de parênteses

  • chamadas de funções

  • expressões matemáticas

Sempre que existir necessidade de "voltar" ao estado anterior, existe uma boa chance de uma Stack resolver o problema.


Filas: O Modelo Natural do Batch

Se existe uma estrutura familiar ao mundo Mainframe é a Queue.

Os Jobs entram.

Esperam.

São executados.

Saem.

JES2 e JES3 vivem exatamente desse conceito.

Fila.

Primeiro que entra.

Primeiro que sai.

O mesmo vale para sistemas de mensagens como IBM MQ.


Linked Lists: Quando a Ordem Importa Mais que a Posição

Em um Array sabemos exatamente onde cada elemento está.

Em uma Linked List sabemos apenas quem é o próximo.

Isso muda completamente a forma de navegar pelos dados.

Um algoritmo famoso utiliza dois ponteiros.

Um anda normalmente.

Outro corre duas posições.

É o famoso algoritmo da Tartaruga e da Lebre.

Ele consegue descobrir ciclos sem utilizar memória adicional.

Uma verdadeira obra de elegância.


Árvores: Muito Mais Presentes do Que Você Imagina

Quando pensamos em árvores normalmente lembramos da faculdade.

Mas elas aparecem diariamente.

Diretórios.

Menus.

JSON.

XML.

LDAP.

Catálogos.

Organogramas.

Até um Plano de Contas contábil é uma árvore.

Quando aprendemos percursos como:

  • Preorder

  • Inorder

  • Postorder

  • Level Order

Estamos aprendendo maneiras diferentes de visitar essa hierarquia.


Grafos: O Modelo Universal

Existe uma frase famosa na Ciência da Computação:

"Tudo pode ser modelado como um grafo."

Internet.

Rotas.

Redes sociais.

Dependências.

Fluxos.

Microserviços.

Tudo isso pode ser representado por nós ligados entre si.

Os principais algoritmos são:

  • BFS

  • DFS

  • Dijkstra

  • Topological Sort

Se você entende esses quatro...

...já resolve uma enorme quantidade de problemas reais.


Programação Dinâmica: A Arte de Não Fazer o Mesmo Trabalho Duas Vezes

Esse talvez seja o assunto que mais assusta iniciantes.

Mas a ideia é incrivelmente simples.

Imagine calcular Fibonacci.

Sem memória:

Fib(40)

↓

Fib(39)

↓

Fib(38)

↓

...

Os mesmos cálculos aparecem centenas de milhares de vezes.

Programação Dinâmica guarda os resultados.

Quando precisar novamente...

...apenas consulta.

No Mainframe fazemos isso frequentemente.

Tabelas em memória.

Caches.

Arquivos temporários.

Tudo isso segue exatamente essa filosofia.


Greedy: A Melhor Decisão Agora

Alguns problemas permitem escolher sempre a melhor opção local.

Quando isso acontece...

...Greedy produz soluções extremamente rápidas.

Mas cuidado.

Nem todo problema aceita essa abordagem.

Saber reconhecer quando Greedy funciona é tão importante quanto conhecer o algoritmo.


Manipulação de Bits: O Poder Escondido do Hardware

Bits ainda são fundamentais.

Operações como:

AND

OR

XOR

SHIFT

São extremamente rápidas.

Mainframes utilizam instruções de hardware especializadas justamente para explorar esse tipo de operação.

Muitos algoritmos de criptografia, compressão e otimização dependem delas.


Estruturas Avançadas

Quando os problemas ficam maiores surgem novas ferramentas.

Segment Trees.

Fenwick Trees.

Sweep Line.

Meet in the Middle.

Essas técnicas aparecem menos no dia a dia, mas são muito comuns em competições de programação e entrevistas de empresas de tecnologia.

Elas demonstram que um mesmo problema pode ser atacado por diferentes estratégias, cada uma adequada a um cenário específico.


O Que Realmente Avaliam em uma Entrevista Técnica?

Muitos imaginam que a empresa quer saber se você decorou o algoritmo de Dijkstra.

Na realidade ela observa outra coisa.

Seu raciocínio.

Ela quer entender se você consegue:

  • Identificar a estrutura de dados correta.

  • Escolher o algoritmo adequado.

  • Explicar por que essa escolha é eficiente.

  • Comparar alternativas.

  • Analisar complexidade de tempo e memória.

  • Escrever um código claro e correto.

A implementação é importante, mas a capacidade de justificar as decisões costuma pesar ainda mais.


O Caminho de Estudos para um COBOL Padawan

Se eu estivesse orientando um jovem programador COBOL hoje, seguiria esta ordem:

  1. Arrays e Strings.

  2. Hash Maps.

  3. Stacks e Queues.

  4. Linked Lists.

  5. Árvores.

  6. Grafos.

  7. Recursão.

  8. Heaps.

  9. Programação Dinâmica.

  10. Técnicas avançadas.

Depois disso, sim, começaria a resolver problemas no LeetCode, HackerRank ou plataformas semelhantes.

Porque, nesse momento, cada exercício deixaria de ser um enigma e passaria a ser um reconhecimento de padrões.


Conclusão: O Verdadeiro Poder Está na Forma de Pensar

Existe um mito de que grandes programadores possuem uma memória extraordinária e conhecem milhares de algoritmos. A realidade é bem diferente. Eles desenvolveram um repertório de padrões e sabem identificar rapidamente qual deles se aplica a um problema.

O programador COBOL possui uma vantagem importante nessa jornada. Décadas trabalhando com arquivos sequenciais, VSAM, DB2, índices, tabelas OCCURS, processamento batch e transações CICS desenvolveram uma disciplina de raciocínio que continua extremamente valiosa. O desafio não é abandonar esse conhecimento, mas traduzi-lo para a linguagem moderna das Estruturas de Dados e Algoritmos.

Quando você perceber que um SEARCH ALL é uma busca binária, que uma tabela OCCURS é um array, que uma fila JES2 segue o princípio de uma queue, ou que um índice DB2 representa uma estrutura otimizada para acesso eficiente, verá que DSA não é um universo distante do Mainframe. É a formalização de conceitos que sempre estiveram presentes.

No fim das contas, programar bem nunca foi sobre decorar centenas de soluções. Sempre foi sobre observar, modelar e resolver problemas da forma mais elegante possível. É essa mentalidade que transforma um Padawan COBOL em um verdadeiro Arquiteto de Software, capaz de navegar tanto pelos sistemas legados que movem bancos e governos quanto pelas tecnologias modernas que definem o futuro da computação.


Sem comentários:

Enviar um comentário