Dúvida sobre progressão dos estudos em Java.
Eu estava começando a estudar complexidade de algoritmos quando um desenvolvedor Junior (sou estagiário) me disse "cara, se tu já estudou algoritmos, então não precisa disso, continua a estudar Banco de dados relacionais Java, pois esse assunto é bom de estudar posteiormente". Como já ficou explícito, já estudei os fundamentos de Java, Estrutura de Controle, Classes e Métodos, Arrays e Collections, POO, Lambdas e Stream API. O tópico posterior do curso a ser estudado é Banco de Dados Relacional, pois isso ele tinha dito isso.
Por que comecei a estudar a complexidade de algoritmos? Estava procurando uns exercícios de algoritmos em Java para aprimorar a minha lógica e velocidade na hora de resolver problemas, mas tais exercícios vinham pedindo um nível de complexidade determinado pela notação Big(O), e por tal motivo comecei a estudar o assunto, para que eu pudesse resolver os exercícios de acordo com o nível de dificuldade requisitado.
A questão é: ter conhecimento de complexidade de algoritmos, bem como saber analisar, é realmente necessário? Acredito que já sei a resposta (ahhhh desculpa se é uma pergunta besta, mas sou besta, fazer oq).
Complexidade de algoritmos é uma daquelas coisas que vc só percebe que faz diferença quando vc conhece. Quem não conhece não vai perceber, na verdade sequer vai chegar a conceber que aquilo pode fazer alguma diferença. Exagerando um pouco, é como se o Tarzan dissesse que pode ir de cipó pra qualquer lugar e isso é o suficiente, pois ele não conhece nenhum outro meio de transporte, e portanto não consegue nem imaginar que há como ir mais rápido.
E o pior de tudo é que, de fato, na maioria dos casos comuns vai "funcionar". Afinal, para poucos dados, tudo é rápido. Hoje os computadores estão tão rápidos, que se um algoritmo tiver que manipular apenas 10, 500 ou 2000 itens, qualquer algoritmo vai ser "rápido".
No artigo indicado acima tem um exemplo claro desse problema. A tabela que tem lá é mais completa, mas enfim, vamos considerar apenas um algoritmo que tem complexidade O(n2) e outro que tem O(nlogn). Veja como a diferença fica cada vez maior conforme o tamanho dos dados aumenta:
n | nlogn | n2 |
---|---|---|
1 | 0 | 1 |
16 | 64 | 256 |
256 | 2.048 | 65.536 |
4.096 | 49.152 | 16.777.216 |
65.536 | 1.048.565 | 4.294.967.296 |
1.048.476 | 20.969.520 | 1,09 trilhões |
16.775.616 | 402.614.784 | 281,4 trilhões |
Ou seja, conforme o N aumenta, o algoritmo O(nlogn) cresce a uma taxa muito menor do que o O(n2). E quanto maior o N, maior a diferença entre os dois.
O problema é que na maioria dos casos mais comuns, lidamos com poucos dados. Páginas e retornos de API web costumam ser paginados, raramente estamos lidando com centenas de milhões de itens. Por isso que na maioria dos casos "funciona" e as pessoas acham que não precisam saber sobre complexidade de algoritmos.
Para poucos itens, qualquer algoritmo rodará em menos de 1 segundo, o que é imperceptível para nós humanos. Mesmo que o algoritmo mais lento demore 0.1 segundo e o mais rápido demore 0.001 segundo (ou seja, 100 vezes mais rápido), ainda sim não perceberíamos a diferença. Só quando tivermos milhões de itens, e o algoritmo mais rápido rodar em 1 minuto enquanto o mais lento demora várias horas, é que as pessoas param para pensar no que estão fazendo.
Outro detalhe é que a complexidade de algoritmos está diretamente ligada a outro assunto importantíssimo: estruturas de dados.
Cada estrutura (fila, pilha, lista ligada, árvore, etc) tem a complexidade de suas operações muito bem documentadas. Por exemplo, "para adicionar elementos é O(n), para buscar um elemento é O(logn), para remover é O(n), etc". E a escolha da estrutura correta pode fazer toda a diferença no algoritmo: o seu caso vai ter mais alterações (adicionar/remover) ou acessos? Os dados precisam estar ordenados ou tanto faz em qual posição adicionar? etc etc etc... Sabendo das necessidades específicas, você consegue escolher a estrutura mais adequada, e essa simples escolha pode fazer toda a diferença no resultado final.
Mas tem gente que não liga pra isso e usa array (ou "objeto") pra tudo (e "funciona", pois sempre tem menos que 100 itens, então tanto faz). Por isso tem tanta gente que diz que não precisa saber, que nunca usou, etc. Só lamento...
Foge dessa pessoa! Sim, pode mostrar isso para ela. Se ela for só ingênua ela vai parar para pensar e revisar sua vida profissional. Mas minha experiência mostra que é comum casos assim não ser só ingenuidade, aí não tem o que fazer, siga a primeira recomendação, tem atitudes que são deletérias. Faça com todo mundo que diga para você aprender menos.
Você tem que estudar toda computação. Bem, quase toda, pelo menos toda a base da computação. Existem algumas coisas que se usam só em alguns casos. Vou contar uma anedota.
Eu fui palestrar em um evento chamado por uma pessoa que é referência para muita gente. Eu falei da complexidade de algoritmo. No fim a turma foi em algum bar e conversando lá ele me disse que em 15 trabalhando na área nunca usou isso. Eu disse que em 35 anos (na época) eu tinha usado todos os dias.
Você acha que o errado é ele que não usou ou eu que uso sem precisar? A pessoa não percebe algo errado se está "funcionando".
Ele precisa fazer umas paradas de microsserviço porque senão o que ele faz não escala. Ele precisa fazer algo complexo para resolver o problema da baixa eficiência do que ele faz. Eu prefiro fazer o eficiente.
Uma vez me disseram que preferem fazer microsserviços porque eles não têm os melhores profissionais para dar eficiência. Mas microsserviços é distribuição, que é o problema mais difícil de fazer certo na computação, e por isso você vê cada vez mais aplicações/sites com dificuldades, vão funcionando aos trancos e barrancos. Complexidade de algoritmo é fundamento. Sem isso você não sabe programar, você engana. Está cada vez mais fácil enganar.
Já estudou os fundamentos da computação? Isso é o que importa. Já aprendeu como o Java funciona para aproveitar bem? Sabe usar a documentação como ninguém? Estão tinindo para resolver problemas, independente da codificação? Sabe estruturar seus dados de forma que atenda melhor às demandas? É nisso tudo que as pessoas pecam e tem a sua evolução comprometida.
A linguagem depois do bem básico você vai aprendendo sob demanda.
Orientação a objeto é um caso à parte. Isso é bem mais complicado do que ensinam e não é fácil achar como aprendi certo. Eu aprendi errado diversas vezes e agora nem sei se já cheguei no certo. Incrível como pessoas bem menos experientes acham que aprenderam certo. E eu vejo publicamente erros grotescos. Mas o importante é funcionar...
É claro que você não precisa ter o conhecimento acadêmico apurado, mas você entender o'que está fazendo pode te poupar muito problema.
Eu me destaquei na vida profissional só por um motivo, eu sei complexidade de algoritmo. Meus grandes feitos, e que alguns classificam como geniais, tamanho o ganho, e que eu sei que foi só eu saber os fundamentos, é bem simples e básico, não tem nada de inteligente no que eu faço, as pessoas se deslumbram porque como elas não entendem aquilo, parece mágica.
Desde a faculdade o que fiz foi o sistema do TCC que levava 3 meses para processar algo virar 20 minutos. O bill of materials que só podia ter 5 níveis de explosão para não ficar dias processando permitiu dezenas e resolver em minutos, ou o caso de qualquer relatório que demorava 30 minutos ou mais para emitir e fiz cair para menos de 30 segundos, alguns quase instantâneos, e fazer toda infra ficar folgada, de brinde. Poderia fazer uma lista enorme.
É por saber dessas coisas que o Stack Overflow, um dos 50 sites mais acessados do mundo (dependendo da época que verifique), pode rodar em 1 servidor, enquanto outros precisam de centenas ou milhares para carga semelhante. E não custa mais caro desenvolver isso, porque quando a pessoa sabe, é só aplicar, não é questão de fazer mais trabalho. Complexo, caro, ineficiente e com qualidade questionável é fazer microsserviços porque não está dando conta da carga de algo muito menor. Ou fazer cache porque tem algo muito ruim por trás (cahce é uma das cosias mais difíceis de administrar, vira e mexe vemos exemplos assim, já vi aqui mesmo).
Isso é parecido com dizer que não precisa de matemática para programação. Programação é matemática. Quando a pessoa diz isso ela não tem noção do que está fazendo.
Busque seu desenvolvimento em tudo, o tempo todo. Não se limite, tenha uma atitude de melhoria contínua, nenhum conhecimento é desperdício. Nunca trabalhei com química, mas de alguma forma foi útil eu ter feito práticas de laboratório na escola. O mesmo para fotografia que me ajudou a ser melhor programador, de formas não convencionais.
Se ajude a pensar cada vez mais. Tenha maneiras de ver problemas sob outras óticas. Sabe a coisa de aprender uma linguagem por ano? É para isso, não é para ter mais chances no mercado de trabalho, é ver como resolver o problema de forma diferente, e melhor. Tudo é questão de atitude, do que escolhe para te acompanhar.
Faz sentido?
Espero ter ajudado.
Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente. Para saber quando, me segue nas suas plataformas preferidas. Quase não as uso, não terá infindas notificações (links aqui).