☕ Um Café no Bellacosa Mainframe
Gostou do conteúdo? Ajude a manter o café quente, o COBOL compilando e o mainframe acordado. 😄
☕ Pague um café ao Bellacosa

Translate

Mostrar mensagens com a etiqueta Árvores. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Árvores. Mostrar todas as mensagens

sexta-feira, 31 de março de 2023

COBOL Recursivo — Muito Além do Fatorial (Parte II Section B)


 

Bellacosa Mainframe apresenta cobol recursivo parte II sec b

☕ Um Café no Bellacosa Mainframe

COBOL Recursivo — Muito Além do Fatorial (Parte 2B)

Quando a Recursividade Deixa de Ser Exercício e Passa a Resolver Problemas Reais no IBM Mainframe

"Depois que um programador entende o Call Stack, surge uma pergunta inevitável: se a recursão é mais lenta que um PERFORM, por que compiladores, bancos de dados, processadores XML e até o próprio z/OS utilizam algoritmos recursivos? A resposta está no tipo de problema que estamos tentando resolver."


Introdução

Na Parte 2A utilizamos o exemplo do fatorial.

Foi uma excelente ferramenta didática.

Mas sejamos honestos.

Você dificilmente encontrará um sistema bancário calculando fatoriais durante o fechamento do dia.

Da mesma forma, poucas empresas utilizam Fibonacci em produção.

Esses algoritmos são importantes porque ensinam os fundamentos.

Entretanto, a verdadeira força da recursividade aparece quando o problema deixa de ser linear.

É exatamente aí que muitos programadores COBOL começam a enxergar a diferença entre escrever código e modelar problemas.

Hoje vamos abandonar os exemplos acadêmicos e explorar situações que realmente aparecem em software corporativo.


O primeiro sinal de que um problema pode ser recursivo

Existe uma pergunta simples.

"O objeto que estou processando pode conter outro objeto igual a ele?"

Se a resposta for sim...

Existe uma grande chance de a recursividade ser uma excelente solução.

Observe.

Uma pasta contém...

Pastas.

Um departamento possui...

Subdepartamentos.

Um XML contém...

Outros elementos XML.

Um menu possui...

Submenus.

Uma árvore possui...

Galhos.

Cada galho possui...

Outros galhos.

O próprio problema descreve sua solução.


Fibonacci: o exemplo que ensina e também alerta

Depois do fatorial, Fibonacci é provavelmente o algoritmo recursivo mais famoso.

F(0)=0

F(1)=1

F(2)=1

F(3)=2

F(4)=3

F(5)=5

F(6)=8

Sua definição é extremamente elegante.

F(N)=F(N-1)+F(N-2)

Visualmente.

               F(6)

          /            \

      F(5)            F(4)

     /    \          /    \

 F(4)    F(3)    F(3)    F(2)

Perceba algo importante.

A mesma conta aparece diversas vezes.

F(4).

F(3).

F(2).

Tudo é recalculado.


O lado sombrio da recursividade

Embora o algoritmo seja bonito...

Ele é extremamente ineficiente.

Imagine calcular:

F(50)

Milhares de chamadas serão repetidas.

A árvore cresce exponencialmente.

É um excelente exemplo de como uma solução elegante pode se tornar um desastre de desempenho.

É por isso que muitos algoritmos recursivos modernos utilizam Memoization (armazenar resultados já calculados) ou são convertidos em versões iterativas quando desempenho extremo é necessário.

Essa é uma lição importante para qualquer Padawan: nem toda recursão elegante é uma boa solução para produção.


Árvores: onde a recursividade realmente brilha

Imagine o organograma de uma empresa.

                Presidente

        /          |           \

 Financeiro       RH          Tecnologia

                 /   \

           Folha     Recrutamento

Cada departamento pode possuir outros departamentos.

Cada um deles pode possuir outros.

Não existe um limite fixo.

Como percorrer isso?


Solução utilizando PERFORM

É possível.

Mas rapidamente surgem:

  • tabelas auxiliares;

  • índices;

  • controle de profundidade;

  • pilhas artificiais;

  • lógica de retorno.

O código cresce.

A manutenção se torna complicada.


Solução recursiva

A lógica passa a ser quase uma descrição em português.

Processe este departamento.

Para cada filho

    processe o filho.

Observe.

A estrutura do algoritmo é praticamente igual à estrutura da árvore.

Esse é o verdadeiro poder da recursividade.


XML: um dos melhores exemplos no Mainframe

Hoje praticamente todo ambiente IBM Z conversa com XML.

Imagine.

<empresa>

   <departamento>

      <funcionario>

         <dependente/>

      </funcionario>

   </departamento>

</empresa>

Cada elemento pode conter outros elementos.

Que podem conter outros elementos.

Que podem conter outros elementos.

Até centenas de níveis.

Como percorrer isso?

Recursivamente.


Visualmente.

Empresa

↓

Departamento

↓

Funcionário

↓

Dependente

Cada elemento executa exatamente o mesmo algoritmo.

"Procure meus filhos."

Se encontrar.

Execute novamente.


JSON segue exatamente a mesma ideia

Imagine.

{
   "cliente":
   {
      "endereco":
      {
         "cidade":
         {
            "bairro":"..."
         }
      }
   }
}

Cada objeto contém outro objeto.

Cada objeto utiliza exatamente a mesma lógica.

É uma árvore.

E árvores gostam de recursão.


O XML PARSER do Enterprise COBOL

Poucos desenvolvedores sabem disso.

Quando utilizamos o recurso XML PARSE do Enterprise COBOL, internamente existe um processamento altamente estruturado para percorrer nós, atributos e elementos aninhados.

Embora a implementação interna da IBM utilize diversas otimizações, o conceito fundamental continua sendo o de navegar por uma estrutura hierárquica.

Esse é um excelente exemplo de como compreender recursividade ajuda a entender tecnologias que usamos diariamente, mesmo sem escrever chamadas recursivas explicitamente.


Sistemas de menus

Imagine um sistema.

Cadastros

↓

Clientes

↓

Endereços

↓

Histórico

Outro menu.

Financeiro

↓

Pagamentos

↓

Boletos

Tudo isso pode ser representado por árvores.

A rotina que desenha um menu pode chamar a si própria sempre que encontrar um submenu.


Diretórios do z/OS UNIX

Embora muitos profissionais associem Mainframe apenas a datasets, o z/OS possui um ambiente UNIX extremamente robusto.

Imagine.

/

├── u

│     ├── vagner

│     ├── projetos

│     └── scripts

└── tmp

Uma rotina que lista diretórios faz exatamente isto.

Entre.

Liste arquivos.

Encontrou pasta?

Entre novamente.

Esse algoritmo praticamente escreve sozinho utilizando recursividade.


Busca em Profundidade (DFS)

Um dos algoritmos mais importantes da Computação.

Depth First Search.

Visualmente.

          A

      /      \

     B        C

   /   \       \

  D     E       F

A busca acontece assim.

A

↓

B

↓

D

↑

B

↓

E

↑

A

↓

C

↓

F

Observe.

Sempre mergulhamos o máximo possível.

Depois retornamos.

Depois continuamos.

Isso acontece naturalmente utilizando recursão.


Busca em Largura (BFS)

Já a Breadth First Search prefere percorrer nível por nível.

Ela normalmente utiliza filas.

Não recursão.

Esse é um ótimo exemplo de que nem todo algoritmo sobre árvores precisa ser recursivo.

O desenvolvedor deve escolher a ferramenta adequada ao problema.


QuickSort

Outro algoritmo clássico.

Imagine.

15

↓

Escolha pivô

↓

Menores

Maiores

↓

Repita para cada lado

Cada metade repete exatamente o mesmo algoritmo.

Recursivamente.


MergeSort

Visualmente.

64 15 10 5

↓

64 15

10 5

↓

64

15

10

5

Quando cada pedaço está ordenado.

Eles são reunidos novamente.

O algoritmo divide.

Depois conquista.

Exatamente como o fatorial.


Divide and Conquer

Existe uma família inteira de algoritmos baseada nesse princípio.

  1. Dividir o problema.

  2. Resolver problemas menores.

  3. Unir os resultados.

Sempre que enxergamos esse padrão, vale a pena perguntar:

"A recursividade simplifica esta solução?"


Árvore B e índices de banco de dados

Db2.

IMS.

VSAM.

Sistemas de arquivos.

Todos utilizam árvores internamente.

Imagine procurar um registro.

Você começa na raiz.

Depois escolhe um galho.

Depois outro.

Depois outro.

Até encontrar a folha.

Embora o código interno dos produtos IBM seja altamente otimizado e frequentemente utilize abordagens iterativas para reduzir consumo de pilha, a lógica conceitual é equivalente ao caminhamento recursivo de uma árvore.


Compiladores

Pouca gente imagina.

Mas compiladores adoram recursão.

Imagine.

A+B*C

Transforma-se em.

          +

      /       \

     A         *

            /     \

           B       C

Cada nó da árvore representa uma operação.

O compilador percorre.

Depois gera código.

Esse processo é conhecido como navegação por uma Árvore Sintática Abstrata (AST).

Mesmo quando a implementação final utiliza otimizações sofisticadas, pensar recursivamente torna a construção dessas estruturas muito mais natural.


Interpretadores

Motores de regras.

Interpretadores.

Calculadoras.

Expressões matemáticas.

Todos trabalham sobre árvores.

Por isso a recursão aparece com frequência.


Onde isso aparece no IBM Z?

Mais do que muitos imaginam.

Alguns exemplos.

  • Processamento XML.

  • Navegação JSON.

  • Ferramentas de análise sintática.

  • Produtos que interpretam linguagens.

  • Utilitários de transformação de documentos.

  • Ferramentas de administração de diretórios USS.

  • Alguns componentes de compiladores e analisadores.

Mesmo que você nunca implemente esses produtos, entender como eles funcionam amplia sua capacidade de projetar soluções.


Um erro muito comum

Depois de aprender recursão.

Alguns desenvolvedores tentam utilizá-la em tudo.

Por exemplo.

Ler arquivo VSAM

↓

Processar registro

↓

Chamar novamente

Não.

Esse é um processamento linear.

O correto continua sendo.

PERFORM UNTIL EOF

Recursão aqui apenas aumenta:

  • consumo de memória;

  • número de chamadas;

  • profundidade da pilha;

  • tempo de execução.

Sem qualquer benefício.


Um teste simples

Antes de decidir.

Pergunte.

Meu problema é:

  • Linear?

ou

  • Hierárquico?

Se for linear.

Use PERFORM.

Se for uma estrutura em árvore.

A recursão provavelmente merece consideração.


A maior lição desta parte

A recursividade não existe para substituir laços.

Ela existe para modelar problemas cuja própria natureza é recursiva.

Quando a estrutura do problema se repete dentro dela mesma, a solução recursiva tende a ser mais elegante, mais legível e mais próxima da forma como pensamos o domínio do problema.

É por isso que ela continua relevante, mesmo em uma linguagem tradicionalmente associada ao processamento sequencial como o COBOL.


Easter Egg Bellacosa ☕

Existe uma curiosidade interessante que raramente aparece em cursos de COBOL.

Quando um programador aprende recursão, normalmente acredita que o objetivo é escrever programas que chamam a si mesmos.

Na prática, o maior ganho costuma ser outro.

Depois de estudar recursividade, muitos desenvolvedores passam a compreender muito melhor:

  • por que existe LOCAL-STORAGE;

  • como funciona o CALL BY REFERENCE;

  • por que o Language Environment (LE) precisa administrar uma pilha de execução;

  • como compiladores preservam contexto entre chamadas;

  • por que produtos como Db2, CICS, XML PARSER e diversos componentes do z/OS conseguem processar estruturas complexas de forma organizada.

Curiosamente, alguns dos programadores COBOL mais experientes que você encontrará talvez nunca tenham escrito uma rotina recursiva em produção. Ainda assim, eles entendem profundamente o conceito porque sabem que recursão é uma ferramenta para compreender arquitetura, não apenas um estilo de programação.


Encerrando o Café

Se o fatorial nos ensinou como uma chamada recursiva nasce e morre, os exemplos desta parte mostram por que essa técnica continua viva mais de sessenta anos depois do surgimento do COBOL.

Árvores, XML, JSON, compiladores, algoritmos de busca e estruturas hierárquicas compartilham uma característica em comum: todos descrevem problemas que contêm versões menores de si mesmos.

É exatamente nesses cenários que a recursividade deixa de ser um exercício de faculdade e passa a ser uma poderosa ferramenta de modelagem.

No próximo café, vamos olhar para a recursão sob a ótica de um Programador Mainframe Sênior. Analisaremos desempenho, consumo de memória, profundidade de pilha, Tail Recursion, otimizações do compilador, depuração, análise de dumps, interação com o Language Environment e diversas dicas práticas para decidir, com segurança, quando usar — e principalmente quando evitar — a recursividade em aplicações Enterprise COBOL.

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.


Vagner Renato Bellacosa, IBM Champion e especialista em IBM Mainframe
IBM Z17 SYSTEM ONLINE
Sobre o autor

Vagner Renato Bellacosa

IBM Champion 2026 • Especialista em IBM Mainframe

Vagner Renato Bellacosa trabalha com IBM Mainframe desde 1988 , é IBM Champion e especialista em COBOL, CICS, Db2, z/OS e IBM Z. Compartilha experiências profissionais, conhecimento técnico, história da computação e práticas do universo mainframe para aproximar novas gerações das tecnologias que sustentam empresas, bancos e governos ao redor do mundo.

IBM Champion IBM Z COBOL CICS Db2 z/OS Mainframe desde 1988
GitHub LinkedIn
Inicializando conteúdo...