Executando verificação de segurança...
3

"Não preciso saber estruturas de dados para programar"

Se você já disse essa frase, parabéns! Você faz parte da geração que acredita que programar é só juntar bibliotecas, copiar código do Stack Overflow e esperar que tudo funcione por mágica. Mas a realidade é dura: se você não entende estruturas de dados, você não programa – você apenas escreve código.

O básico que (quase) ninguém quer aprender

Claro, você pode criar aplicações sem saber o que é uma árvore AVL, um heap binário ou um grafo direcionado. Mas eventualmente você vai se deparar com um problema onde um simples for loop não resolve e, adivinhe? Você não vai saber por onde começar.

Se você não entende como funciona uma lista ligada, por que raios está escolhendo entre um ArrayList e um LinkedList no Java? Se não sabe a diferença entre busca binária e busca linear, como vai otimizar suas consultas no banco? Se nunca estudou tabelas hash, como espera lidar com caches eficientes?

O código que você escreve poderia ser melhor

O que acontece quando alguém que "não precisa saber estruturas de dados" tenta resolver problemas complexos? O código vira um pesadelo de loops aninhados, consumo de memória desnecessário e processamento absurdo. No final, alguém mais experiente terá que refatorar tudo para não explodir o servidor em produção.

E não precisa ser algo super avançado. Quer um exemplo básico? Aqui estão duas formas de buscar um item em uma lista:

Método de quem "não precisa saber estruturas de dados"

lista = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
alvo = 7

for item in lista:
    if item == alvo:
        print("Encontrado!")

Método de quem sabe o básico

lista = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
alvo = 7

if alvo in set(lista):
    print("Encontrado!")

O segundo código converte a lista em um conjunto (set), tornando a busca O(1) em vez de O(n). Se você não sabe o que isso significa, aí está o problema.

"Mas eu sou desenvolvedor frontend, não preciso disso!"

Ah, sim. Porque interfaces modernas não precisam manipular grandes volumes de dados, certo? Então por que bibliotecas como React, Vue e Svelte se preocupam tanto com renderização eficiente, atualização de estado e manipulação otimizada do DOM? Você pode até não escrever árvores de busca no dia a dia, mas garanto que saber como funciona um Virtual DOM ou um diffing algorithm vai tornar você um desenvolvedor frontend muito melhor.

Conclusão

Você pode até programar sem entender estruturas de dados profundamente, mas isso significa que sempre dependerá de ferramentas que outras pessoas criaram. Seu código será mais lento, menos eficiente e, quando surgirem problemas reais, você não saberá como resolvê-los.

Então, pare de fugir do aprendizado. Você não precisa se tornar um cientista da computação, mas se quer ser um programador de verdade, aprender estruturas de dados é o mínimo que se espera. Simples assim.

Carregando publicação patrocinada...
13

Se o custo de criar o set é O(n), não faz sentido criar um set para fazer uma busca, ainda mais falando sobre uma lista de 10 elementos.

Faz sentido sugerir estudar estrutura de dados, mas é preciso usar exemplos melhores para mostrar a utilidade.

3

Era o que ia falar.

Criar o set faz sentido se vc vai fazer muitas buscas e/ou tiver muitos elementos, pois aí o custo de criá-lo se paga.

Mas se é só para uma ou poucas buscas (ou listas com poucos elementos), pode até piorar. Ou no melhor caso, tanto faz porque a diferença será irrisória e imperceptível - afinal, para poucos dados, tudo é rápido.

Dito isso, gosto da mensagem geral, de que conhecer as estruturas de dados é importante. Vejo muito código desnecessariamente complicado ou ineficiente por aí, simplesmente porque a pessoa está usando a estrutura errada.

2

Exatamente! A conversão para set só faz sentido quando há múltiplas buscas ou um grande volume de dados, pois o custo de criação se paga nesses casos. Para listas pequenas ou poucas buscas, a diferença pode ser insignificante ou até piorar a performance. O exemplo poderia ter sido melhor escolhido, mas a ideia principal continua sendo a importância de conhecer estruturas de dados para evitar códigos desnecessariamente complicados ou ineficientes. Muitas vezes, a escolha errada da estrutura pode impactar mais do que parece!

Eu tinha uns 20 exemplos e escolhi o pior, no proximo post eu melhoro, obrigado!

1
0

Ótima observação! De fato, criar um set tem um custo O(n), então para uma única busca em uma lista pequena, a abordagem não traz vantagem. O exemplo poderia ser melhor ajustado para um cenário onde múltiplas buscas são feitas, justificando a conversão para set antes das consultas. O ponto principal do post, no entanto, continua sendo a importância de entender estruturas de dados para tomar decisões informadas e otimizar código quando necessário.

No proximo post eu melhoro o exemplo, obrigado pelo comentario

1

Retornei apenas para dizer que seu post foi útil para mim, pois após ler e não entender o que é O(n) fui estudar e aprendi a notação matemática Big O e as possíveis ordens de crescimento e como isso afeta o desempenho do código. Inclusive fiz um estudo pesado sobre o método sort() do JS, entendendo exatamente o que acontece durante a execução e quantos cálculos ele faz aproximadamente para realizar a ordenação de n elementos, classificado como O(n log n).

Seu exemplo pode não ter sido o melhor, mas a intenção foi boa o suficiente para me levar a aprender algo novo e útil. Agradeço.

1

De qualquer forma eu não entendi nada quando você disse O(n). Então, com licença, vou estudar e volto pra conversar quando estiver mais informado.

3

Já falaram isso mas acho importante reforçar: O código de exemplo dado no post é ruim. Na verdade a sua alteração piora a performance ao invés de melhorar.

Concordo plenamente com a mensagem do post, de qualquer forma. Mas toma cuidado que entre a loucura e a genialidade existe uma linha tênue. Você parecia muito confiante que o exemplo que você escreveu era de fato uma melhoria e de fato o código ficou mais performático, quando na verdade é exatamente o oposto e tecnicamente o código ficou "pior".

Dica: Confiança demais cega.

Inclusive, coincidentemente, hoje eu postei um artigo sobre otimização de código no TabNews. Com poucos minutos de diferença da sua publicação, a propósito kkkk.

Se você tem interesse em aprender sobre otimização de código, eu sugiro a leitura:

Eu sugiro que leia o artigo e cuidado ao acreditar nestas supertições sobre otimização de código. É bem comum eu ver gente acreditando nestas coisas e piorando a performance do código enquanto acredita que está "otimizando" ele.

0

Boa observação! De fato, o exemplo dado no post poderia ter sido melhor escolhido, já que a conversão para set tem um custo inicial que não compensa para buscas isoladas ou listas pequenas. A ideia era ilustrar como a escolha da estrutura de dados pode impactar o desempenho, mas reconheço que nesse caso específico o efeito foi o oposto.

Agradeço a recomendação do artigo, sempre bom trocar ideias sobre otimização de código! No fim das contas, o ponto principal continua sendo que conhecer bem estruturas de dados ajuda a evitar armadilhas de desempenho e tomar decisões mais informadas. Valeu pelo feedback!

2

Todo mundo falando que o exemplo é ruim (de fato é). Vou dar um exemplo real.

Numa determinada rotina tinha algo assim (java):

if (!codigos.contains(codigo)) {
  codigos.add(codigo);
  rotina(codigo);
}

A questão é que códigos acima era um List. Trocamos por um HashSet e o codigo final ficou

if (codigos.add(codigo)) {
  rotina(codigo);
}

Ou seja, se add retornar true é porque o elemento não existia no set e foi adicionado então podemos rodar a rotina. Como tinha bastante elementos a diferença foi muito perceptível.

0

Ótimo exemplo! Esse caso ilustra bem como a escolha correta da estrutura de dados pode impactar a performance. Usar um HashSet em vez de uma List para verificar e armazenar elementos reduz o tempo de busca de O(n) para O(1) na maioria dos casos, tornando o código mais eficiente, especialmente em conjuntos grandes.

A ideia do post era justamente reforçar a importância de entender essas diferenças, mas concordo que o exemplo escolhido não foi o melhor. Valeu por compartilhar um caso real que demonstra bem esse princípio!

Obrigado pelo comentario!

1

SIM É IMPORTANTE SABER OS FUNDAMENTOS, DITO ISSO....

Na teoria, você está certo, mas, na prática, as pessoas que você afirma não saber programar estão empregadas, trabalhando diariamente e recebendo seus salários. Enquanto isso, as empresas que contratam esses profissionais continuam faturando milhões com a venda de seus softwares e soluções tecnológicas.

Enquanto você se estressa com essa situação, essas empresas seguem prosperando e expandindo seus negócios, muitas vezes sem se preocupar com a perfeição do código, mas sim com os resultados que ele proporciona. No final das contas, o que realmente importa para as empresas é o lucro, e para os usuários, a entrega de valor.

Se a solução foi desenvolvida com inteligência artificial, low-code, no-code, C#, Python, PHP, Delphi ou até mesmo Assembly, isso pouco importa para o cliente final. Da mesma forma, se a implementação usou dicionários ou listas, esse detalhe técnico não faz diferença para quem está consumindo o produto. No fim das contas, tudo gira em torno da entrega de valor e da resolução de problemas, não necessariamente da pureza do código ou da tecnologia utilizada.

1

Excelente! Só uma observação:

O tamanho da lista importa quando estamos criando um algoritmo de pesquisa ou manipulação de estruturas de dados.

Recentemente complementei meus estudos em java sobre testes de desempenho e eficiência sobre o uso de LinkedList e ArrayList. Percebi que a disparidade entre ambos é grande conforme seus tamanhos aumentam.

ArrayList geralmente é o melhor pra maioria dos cenários, mas o consumo de memória é terrivel, pois um ArrayList cresce exponencialmente, mas nao diminui na mesma proporção que cresce quando você remove itens, e isso o torna muito grande e lotado de espaços vazios.

Mas, de qualquer forma, estruturas de dados é um tema pra quem realmente gosta, não pra entusiastas da programação que acham que o código trabalha sozinho como um quebra cabeças, sem precisar de intervenção constante e excessiva da mente humana. É um tema que eu particularmente tenho muito apreço.

1

Concordo que o segundo codigo tem um melhor desempenho em relação ao primeiro, apesar de ambos serem codigo bem simples e que é imperceptível a diferença em ambos, contudo se aumentamos o grau de ficiculdade poderemos então contastar isso. Basta realizar a mesma tarefa com tres listas e três alvos diferente com o intuito de verificar se os três alvos estão nas três lista simultaneamente e poderemos notar o quanto diferente será a performace dos dois codigos.
Enquanto o primeiro realizará a dura tarefa de:
O(n) x O(n) x O(n) que no caso da listas possuir 10 elementos estaríamos falando de até 1000 interações
o segundo realizara a tarefa de
O(n) + O(n) + O(n) que no caso da listas possuir 10 elementos estaríamos falando de apenas 30 interações isso claro levando em conta que a conversao da lista em set lhe custe um O(n). O que nos leva a conclusão de que mesmo que haja um custo na conversão da lista para set ela será muito util para um melhor desemepnho ao realizar a busca.

1

Você não está avaliando apropriadamente a performance. E sua explicação para alegar que o segundo código é mais rápido não faz sentido, pois é literalmente necessário alterar o código para isso ser verdade. Levando em consideração o código que realmente está escrito no post, o segundo é pior em performance.

E se for para ter "licença poética" de modificar o código para dizer qual é mais rápido, então podemos modificar o primeiro para usar uma busca binária ao invés de busca linear. Logo é O(log n) (primeiro código) VS O(n) (segundo código), ou seja, o primeiro código é mais rápido.

E isso só levando em consideração o óbvio, mas podemos levar em consideração outros fatores também: O tipo list é implementado como dynamic array e o tipo set como hashtable. Considerando isto:

  1. Dynamic array consome menos memória que hashtable.
  2. Dynamic array é muito mais "cache friendly" do que hashtable, logo é mais perfomático para o processador.
  3. Inserções em dynamic arrays sempre são O(1), mas inserções em hashtable são O((log n)^2) no pior caso.
  4. Busca binária é O(log n) no pior caso e busca em hashtable é O((log n)^2) no pior caso.
  5. A conversão de list para set causa alocação de memória implícita, que consome recursos a mais tanto de memória quanto de CPU comparado a simplesmente trabalhar com a list diretamente.
  6. Já que o set() é alocado no escopo do if, então ele é alocado e imediatamente desalocado em seguida. Dando trabalho extra para o GC com uma estrutura que será usada em uma única operação.

Conclusão: Por vários motivos o primeiro código é mais performático que o segundo.

0

Ótima análise! De fato, se formos avaliar a implementação real do código no post, a conversão para set ali não faz sentido e acaba piorando a performance. A intenção era mostrar como a escolha da estrutura de dados pode impactar a eficiência, mas concordo que o exemplo não foi feliz e acabou gerando um efeito contrário.

Seu ponto sobre busca binária faz total sentido, e considerando a estrutura interna de list e set, há diversos fatores além da complexidade assintótica que influenciam no desempenho real, como consumo de memória, cache locality e até o comportamento do GC.

A lição que fica disso tudo é que otimização não é apenas sobre big-O, mas também sobre o comportamento real das estruturas e do hardware. Obrigado pelo comentário, sempre bom discutir esses detalhes!

0

Faz sentido! Em casos onde há múltiplas buscas em grandes volumes de dados, o custo inicial da conversão para set se paga rapidamente, reduzindo o número total de operações. Seu exemplo ilustra bem essa diferença, mostrando que a complexidade computacional pode escalar muito dependendo da abordagem escolhida.

O ponto central do post era exatamente esse: entender as estruturas de dados permite tomar decisões mais inteligentes e evitar gargalos de performance. Valeu pelo comentário!

1
0

Ótima pergunta! Algumas das estruturas de dados mais importantes para um desenvolvedor entender são:

  • Arrays e Listas Ligadas – Fundamentais para armazenar e manipular coleções de dados. Saber quando usar cada uma evita desperdício de memória ou operações lentas.

  • Pilhas e Filas – Muito usadas em algoritmos, como backtracking e processamento de tarefas (ex: filas de mensagens, navegação no histórico do navegador).

  • Hash Tables (Dicionários/Mapas) – Essenciais para buscas rápidas, caches e armazenamento eficiente de pares chave-valor.

  • Árvores (como BSTs, Heaps e Tries) – Úteis para organizar dados hierárquicos, realizar buscas rápidas e implementar estruturas como bancos de dados e compiladores.

  • Grafos – Fundamentais para modelar relações complexas, como redes sociais, mapas e sistemas de recomendação.

Cada uma tem seu lugar, e conhecer seus pontos fortes e fracos ajuda a escrever códigos mais eficientes e escaláveis!"

0
1

Na verdade o list do Python é um tipo e não uma estrutura de dados. Por baixo dos panos o tipo list do Python é implementado como um dynamic array, este sim se tratando de uma estrutura de dados.