Por que é melhor para um programador projetar o algoritmo antes de começar a escrever o código?

12

Um algoritmo apropriado realmente ajuda a melhorar a qualidade e, finalmente, a eficiência de um programa?

Ainda podemos produzir um programa de boa qualidade sem o algoritmo?

Um algoritmo apropriado é obrigatório na programação moderna?

Jervis
fonte
5
Por definição, existe algum algoritmo, mesmo que seja tão ruim que seja bom .
5
Eu não tenho escolha a não ser codificar código em vez de pensar demais. Na maioria das vezes, não há algoritmo glorioso para nenhum padrão; Eu estou apenas tentando polir uma bosta fedorenta;)
Job
13
Não acredito que essa seja uma pergunta séria. Veja en.wikipedia.org/wiki/Algorithm
Steven A. Lowe
2
O título é razoável, mas o texto da pergunta menos. Acho que ele está perguntando se o algoritmo precisa ser pregado antes que se possa começar a escrever o código real.
Greg
9
Eu digo que não ... é sempre melhor dirigir sem rumo até encontrar o seu destino por acidente ou ficar sem combustível.
JMQ

Respostas:

29

Penso que esta questão implora alguma perspectiva histórica.

Nos velhos tempos (dos quais eu não sou uma testemunha pessoal, essa é apenas a minha reconstrução daquela época - sinta-se à vontade para me corrigir se você tiver experimentado as coisas de maneira diferente) O espaço e o desempenho do HW eram nulos em comparação aos de hoje. Então, tudo o que as pessoas escreviam tinha que ser muito eficiente. Portanto, eles precisavam pensar muito e pesquisar para inventar os melhores algoritmos para obter o desempenho de espaço / tempo necessário para realizar o trabalho. Outro fator foi que os desenvolvedores estavam trabalhando principalmente no que você pode chamar de infraestrutura : sistemas operacionais, pilhas de protocolos, compiladores, drivers de dispositivo, editores etc. Tudo isso é muito usado por muitas pessoas, portanto o desempenho realmente faz a diferença .

Hoje em dia, somos estragados por ter um HW incrível com processadores multicore e Gigabytes de memória, mesmo em um laptop básico (diabos, mesmo em um telefone celular). O que significa naturalmente que, em muitos casos, o desempenho - portanto, o algoritmo - deixou de ser o problema central, e é mais importante fornecer uma solução rapidamente do que fornecer uma solução rápida. OTOH, temos montes de estruturas que nos ajudam a resolver problemas e encapsulam um grande número de algoritmos ao mesmo tempo. Portanto, mesmo quando não estamos pensando em algoritmos, podemos muito bem estar usando muitos deles em segundo plano.

No entanto, ainda existem áreas em que o desempenho é importante. Nessas áreas, você ainda precisa pensar muito em seus algoritmos antes de escrever o código. O motivo é que o algoritmo é o centro do design, determinando muitas estruturas de dados e relacionamentos no código circundante. E se você descobrir tarde demais que seu algoritmo não está escalando bem (por exemplo, ele é O (n 3 ), parecia agradável e rápido quando você o testou em 10 itens, mas na vida real você terá milhões), é muito difícil, propenso a erros e demorado para substituí-lo no código de produção. E as micro otimizações não vão ajudá-lo se o algoritmo fundamental não for adequado para o trabalho.

Péter Török
fonte
1
Que resposta. É meu privilégio tê-lo aqui !!!
Jervis
5
Além disso, o computador era muito mais caro que o programador, por isso fazia sentido fazê-lo trabalhar mais!
2
Você está certo de que o que estamos otimizando mudou. Agora, espera-se que agora manipulemos sistemas muito mais complexos do que as pessoas na época. Uma falta de pensamento sobre planejamento, organização e manutenção ainda o matará.
btilly
1
@btilly, concordo que é muito importante planejar com antecedência (o máximo possível - mas não mais) e pensar em manutenção com antecedência. No entanto, isso não significa necessariamente gastar muito tempo no design de algoritmos. Por exemplo, se uma função é executada uma vez por mês e leva uma hora para terminar, provavelmente é um exagero passar dias no ajuste de algoritmos, mesmo que você consiga reduzir o tempo de execução para 10 minutos. Os benefícios simplesmente não justificam o custo.
Péter Török
2
Duas coisas: primeiro, o algoritmo pode determinar o quão bem o programa é escalável, e isso geralmente é importante. Segundo, muitos softwares são executados em paralelo nos servidores atualmente. Isso significa que, se o programa Z for modificado para ser executado duas vezes mais rápido, quem o estiver executando precisará de metade do número de servidores Z.
David Thornley
14

Apenas para apontar algo:

Um algoritmo é ele próprio uma solução passo a passo geral do seu problema. Portanto, se você resolveu o problema, de fato usou um algoritmo.

O ponto mais importante aqui é que você deve usar algoritmos para resolver problemas, de uma maneira ou de outra. Na maioria das vezes, é melhor pensar no seu problema antes de passar para a codificação - essa fase costuma ser chamada de design. Mas quanto e de que maneira você fará isso depende de você.

Além disso, você não deve misturar o conceito de algoritmo com fluxogramas (suspeito que isso esteja acontecendo aqui). Os fluxogramas são apenas uma representação gráfica que pode ser usada e usada nos dias anteriores para ilustrar um algoritmo. É praticamente obsoleto hoje em dia.

EDITAR:

De fato, existem muitas maneiras de representar um algoritmo e o próprio código da linguagem de programação é uma delas. No entanto, muitas vezes é muito melhor ou mais fácil não resolver todo o problema de uma só vez, mas apenas um esboço e preencher os espaços em branco à medida que avança.

  • Meu favorito pessoal aqui é o pseudo-código, e apenas para cobrir um resumo geral geral do algoritmo em questão - é ridículo entrar em detalhes com o pseudocódigo , é para isso que serve o código real.

  • Mas o código real pode ser usado para o esboço. Por exemplo, as pessoas do TDD gostam de projetar o algoritmo à medida que codificam e, como também não podem resolver tudo de uma vez, elas projetam um esboço da execução do programa em código real e usam objetos simulados (ou funções, métodos .. .) como espaços em branco a serem preenchidos posteriormente.

  • Os diagramas de atividades UML parecem ser uma encarnação moderna de fluxogramas de estilo antigo, com notação adicional para novos itens, como polimorfismo e multithreading. Eu realmente não posso dizer o quão útil isso é, já que eu realmente não os usei muito - estou apenas mencionando isso para ser completo.

  • Além disso, se você estiver baseando seu algoritmo na alternância entre estados, um diagrama de estados será bastante útil.

  • Geralmente, qualquer meio que você precise simplesmente esboçar a ideia por trás de um determinado algoritmo é um bom caminho a percorrer.

Goran Jovic
fonte
Existem muitas maneiras diferentes de apresentar o algoritmo, que você recomenda? E porque?
Jervis
@Ervis: Veja minha atualização, listei alguns deles.
Goran Jovic 21/02
Onde está o link?
Jervis
4

Uma boa analogia é que você deve conhecer uma receita antes de começar a cozinhar. Ok, você pode ajustá-lo à medida que avança, mas ainda precisa saber o que deseja fazer antes de começar. Se eu quiser fazer um ensopado de borrego, farei coisas muito diferentes do que se eu quiser assar um pedaço de pão.

Zachary K
fonte
Algoritmo = idéias ???
Jervis
Algoritmo == receita !!
Mas chefs diferentes têm maneiras diferentes de cozinhar de acordo com a mesma receita.
Jervis
Claro, quando eu asso pão, sai diferente de quando minha esposa assa pão. Mas as partes básicas são as mesmas (farinha, água, fermento, sal)
Zachary K
Também existem lojas onde você pode simplesmente comprar um pedaço de pão feito por um padeiro profissional
jk.
3

Código implementa algoritmos. Tentar escrever código sem ter projetado o algoritmo é como tentar pintar uma casa antes que as paredes sejam construídas. Os algoritmos têm sido um "DEVE" desde o início da programação.

Jerry Coffin
fonte
ESTÁ BEM. Pintar uma casa é tão fácil quanto o ABC, você pode começar a planejar sem a existência da casa.
Jervis
2
@Jervis: Da mesma forma, você pode planejar algumas partes do código sem especificar o algoritmo para outras partes (por exemplo, você pode decidir que haverá uma função para classificar os dados sem decidir como funcionará - mas você precisa decidir quando quiser escreva o código de classificação).
Jerry Coffin
1
Prefiro a analogia de pintar uma imagem do que pintar uma casa. Se toda a minha codificação fosse como pintar uma casa, encontraria outro emprego. E pintar uma imagem pode ser iterativo. Costumo iniciar a criação de protótipos em código real antes que o algoritmo seja completamente claro para mim. Na maioria das vezes, de fato.
Greg
3

Ser fluente no seu idioma ajuda a melhorar a qualidade e a produtividade. Resolver pequenos problemas algorítmicos é muito mais útil para isso do que repetir o mesmo material MVC 100 vezes.
Embora, suponha que haja outras maneiras de obter fluência.

O algoritmo se tornará uma obrigação no domínio da programação moderna?
Já é um 'must', a menos que você seja um 'php ninja' escrevendo 'cool codez'. Todas as 'melhores' empresas (Google, Amazon etc.) testam sua experiência algorítmica em entrevistas, e imagino que não fariam isso por nenhuma razão.

Mas voltando ao ponto original, você deve se desafiar constantemente, se quiser melhorar. E como os trabalhos normais (também conhecidos como "agora escrevem gerentes CRUD para mais 100 objetos") nem sempre oferecem um bom desafio, os algoritmos compensam isso.

Nikita Rybak
fonte
1

Eu diria que você precisa de pelo menos uma idéia inicial de um algoritmo antes de começar a codificar. Você provavelmente revisará sua ideia ao codificar com base em estruturas de dados etc.

Posteriormente, você poderá revisar o código novamente se a criação de perfil sugerir que há um problema de desempenho nessa área.

Richard Miskin
fonte
1

O motivo é que é mais rápido corrigir erros antes de você escrever o código errado.

Mais prosaicamente, existem rotineiramente diferenças de produtividade de 10 para 1 entre diferentes programadores. Quando você olha para os programadores que estão no nível de produtividade 10 vezes maior, eles passam a menor fração de seu tempo realmente codificando. Hora de digitar o código não deve ser o gargalo. Em vez disso, eles gastam uma fração maior do seu tempo para garantir que eles tenham requisitos diretos, planejamento, testes etc.

Por outro lado, quando você olha para os programadores que mergulham na codificação sem uma pausa, eles inevitavelmente precisam escrever o código repetidamente, pois encontram problemas totalmente previsíveis, e o resultado final é menos sustentável e com erros. (Aliás, você sabia que uma média de 80% do dinheiro gasto no desenvolvimento de software está na fase de manutenção? Tornar as coisas importantes para a manutenção. Muito.)

btilly
fonte
Você está absolutamente certo.
Jervis
1

Geralmente algoritmos e estruturas de dados primeiro, código depois. Mas isso depende muito do domínio de programação. Eu costumava fazer um monte de coisas do tipo matemática aplicada e realmente olhava para o modelo em cascata predominante na época. Isso porque os algoritmos de nível baixo a médio raramente podiam ser tomados como garantidos. Crie uma grande estrutura em torno da existência de subsistemas não escritos e descubra no final do jogo que a matemática de um desses subsistemas cruciais não funciona (é instável ou o que for). Por isso, sempre pensei nos subsistemas mais desafiadores primeiro e, se havia alguma razão para dúvida, escrevi e testei os primeiros. Mas, para alguns domínios problemáticos, você pode seguir em frente sem muito planejamento.

Omega Centauri
fonte
Eu concordo com você.
Jervis
Você está falando aqui sobre a diferença entre o design de cima para baixo e o de baixo para cima, que é uma questão diferente. Quando você "segue adiante", ainda está implementando algum tipo de algoritmo. Você pode não pensar nisso nesses termos, talvez porque o algoritmo lhe pareça óbvio ou porque já esteja familiarizado com o problema, mas isso não significa que o algoritmo ainda não esteja lá.
Caleb
0

Crie um algoritmo em seções, depois divida essas seções e codifique cada uma delas individualmente. Dessa forma, você pode misturar os dois pontos de vista:

  1. Use seus recursos de idioma para obter o melhor desempenho possível
  2. Tente pensar antes do código, para que sua ideia não se mescle ao idioma (um dia você precisará mover seu algoritmo para outro idioma e terminará un em spagetthi)
guiman
fonte
Yap! Eu sei que o algoritmo é independente da linguagem. É verdade que você pode usar qualquer linguagem de programação existente para expressar o mesmo algoritmo.
Jervis
0

Para mim, é praticamente todo o código. Eu acho que isso é verdade para a maioria dos programadores altamente produtivos. Eu posso escrever código tão facilmente quanto escrevo texto.

Na medida do possível, tento capturar requisitos como testes executáveis ​​(código). O design é apenas uma codificação de alto nível. É mais rápido e preciso capturar o design no idioma de destino do que capturá-lo de alguma outra forma e depois traduzi-lo.

Descobri que a maioria dos usuários não pode revisar efetivamente os requisitos de texto. Eles funcionam bem com casos de uso seqüenciais, mas os casos de uso não podem capturar todos os aspectos da interface do usuário. De longe, o melhor é fazer um primeiro corte na implementação, permitir que os usuários experimentem, obtenham seus comentários e modifiquem o código de acordo.

Kevin Cline
fonte
0

Quando você se senta e começa a codificar, tem um algoritmo em mente, seja "projetado" ou não.

Se você sentou-se e começou a codificar sem um algoritmo completo em mente, faria o seguinte:

1) esmagando teclas aleatoriamente. Isso provavelmente produzirá um erro do compilador

2) escrever código compilável que provavelmente faz qualquer coisa, exceto o que você deseja que ele faça

3) escrever código para resolver pequenas partes do problema e desenvolvê-lo à medida que você avança de maneira agregada, mas sem realmente pensar no futuro - para que eventualmente o problema seja resolvido - mas o código não é uma maneira muito eficiente e com possibilidade de ter que voltar atrás e perder tempo ao longo do caminho

Então, as pessoas costumam programar com um algoritmo na cabeça. Pode ter sido elaborado ou discutido no papel ou em outro meio.

Pode ser uma boa disciplina pensar no seu ataque a um problema fora do teclado, especialmente em seus primeiros dias como programador. Como outras respostas observaram, à medida que você se torna mais experiente, pode melhorar a codificação de alguns pedaços mais gerenciáveis ​​do problema "on the fly". No entanto, para problemas difíceis ou grandes, é útil pensar e projetar longe do teclado: quando envolvido com código, é mais provável que você pense em termos de construções da linguagem e em como abordar a tarefa mais imediata no problema. Considerando que pensar no problema com, digamos, caneta e papel, libera você mais do aspecto da linguagem do código e permite que você pense em um nível mais alto e abstrato.

occulus
fonte
0

Você precisa parar de olhar para a construção de software como algo fundamental a partir da construção de qualquer outra coisa de valor. Não é. Portanto, como qualquer outra coisa, sempre é necessário um plano ou projeto bem pensado, mesmo que sucinto.

Um algoritmo apropriado realmente ajuda a melhorar a qualidade e, finalmente, a eficiência de um programa?

Um plano / esquema de construção apropriado ajuda a construir uma casa de qualidade com eficiência?

Ainda podemos produzir um programa de boa qualidade sem o algoritmo?

Você pode construir uma casa de boa qualidade com eficiência, sem um plano de construção adequado? De acordo com o Teorema do Macaco Infinito , probabilisticamente, sim (assim como um milhão de macacos digitando aleatoriamente por toda a eternidade acabará digitando as obras completas de Shakespeare.

Um algoritmo apropriado é obrigatório na programação moderna?

Se você não quer ser um macaco de código e deseja garantir que não entrega um software que pareça e funcione como uma merda, sim, é uma obrigação. Todo projeto que eu tive que salvar (porque o código parecia uma merda sustentável) começou invariável com uma resposta negativa a essa pergunta.

De fato, a programação moderna foi o afastamento do engenheiro de software de programação de cowboys, onde o planejamento de algum tipo, se necessário.

Mesmo quando você tem uma biblioteca de algoritmos e estruturas de dados à sua disposição (ou seja, Boost no C ++ ou na biblioteca de coleções Java), você precisa saber como essas coisas funcionam para usá-las adequadamente e compor em razoáveis ​​e superiores. algoritmos de nível.

luis.espinal
fonte
-2

Não é melhor É melhor não "projetar" nada. Isso é para pessoas que não escrevem programas. Você sabe, as pessoas com experiência real do problema em questão. Se você é matemático, engenheiro ou logístico, tudo bem, você precisa trabalhar no processo em outro lugar. Mas isso não é 'programação'.

Coloque algum tipo de teste e referência em primeiro lugar.

Então escreva algo, qualquer coisa. Refatorar-reescrever-loop até ficar sem tempo ou não conseguir mais melhorar.

Enquanto muitos parecem pensar que é possível fazer coisas com um computador sem fazer nada no computador, acho que esse é um dos mitos mais comuns por aí. Astronautismos de arquitetura.

Além disso, você não pode otimizar seu algo antes que ele seja gravado.

IOW, "fique perto do metal".

Casimir Pohjanraito
fonte