Por que alguns programadores acham que existe um contraste entre teoria e prática? [fechadas]


63

Comparando a engenharia de software com a engenharia civil, fiquei surpreso ao observar uma maneira diferente de pensar: qualquer engenheiro civil sabe que, se você quiser construir uma pequena cabana no jardim, poderá obter os materiais e construí-lo, enquanto que, se quiser construir uma casa de 10 andares (ou, por exemplo, algo como este ) que você precisa fazer muito algumas matemática para ter certeza que ele não vai desmoronar.

Por outro lado, conversando com alguns programadores ou lendo blogs ou fóruns, muitas vezes encontro uma opinião ampla que pode ser formulada mais ou menos da seguinte maneira: teoria e métodos formais são para matemáticos / cientistas, enquanto a programação é mais para fazer as coisas .

O que normalmente está implícito aqui é que a programação é algo muito prático e que, embora métodos formais, matemática, teoria de algoritmos, linguagens de programação limpas / coerentes, etc, possam ser tópicos interessantes, muitas vezes não são necessários se tudo o que se quer é conseguir coisas feito .

De acordo com minha experiência, eu diria que, embora você não precise de muita teoria para montar um script de 100 linhas (a cabana), para desenvolver um aplicativo complexo (o prédio de 10 andares), você precisa de um design estruturado, bem -definidos métodos, uma boa linguagem de programação, bons livros de texto onde você pode procurar algoritmos, etc.

Portanto, a teoria da IMO (a quantidade certa de) é uma das ferramentas para realizar as tarefas .

Minha pergunta é por que alguns programadores pensam que existe um contraste entre teoria (métodos formais) e prática (fazer as coisas)?

A engenharia de software (software de construção) é percebida por muitos como fácil em comparação com, digamos, a engenharia civil (construção de casas)?

Ou essas duas disciplinas são realmente diferentes (além do software de missão crítica, a falha de software é muito mais aceitável do que a falha de construção)?


Tento resumir o que entendi das respostas até agora.

  1. Ao contrário da engenharia de software, na engenharia civil é muito mais claro que quantidade de teoria (modelagem, design) é necessária para uma determinada tarefa.
  2. Isso se deve em parte ao fato de que a engenharia civil é tão antiga quanto a humanidade, enquanto a engenharia de software existe há apenas algumas décadas.
  3. Outro motivo é o fato de o software ser um tipo de artefato mais volátil, com requisitos mais flexíveis (pode ser permitido travar), diferentes estratégias de marketing (um bom design pode ser sacrificado para colocá-lo no mercado rapidamente), etc.

Como conseqüência, é muito mais difícil determinar qual a quantidade certa de projeto / teoria é apropriada na engenharia de software (muito pouco -> código confuso, muito -> nunca consigo terminar) porque não há regra geral e apenas (muita) experiência pode ajudar.

Portanto, se eu interpretar suas respostas corretamente, essa incerteza sobre quanta teoria é realmente necessária contribui para os sentimentos mistos de amor / ódio que alguns programadores têm em relação à teoria.


9
não, 90% dos programadores são;)
jk.

24
Bem, no software, você pode começar construindo o telhado e seguir até a fundação, enquanto as peças acabadas estão flutuando no ar. Se algo não estiver adequado, você pode usar fita adesiva para ajustá-lo. Tente isso ao construir um arranha-céu. ;)
Secure

65
Na teoria, não há diferença entre teoria e prática, mas na prática existe.
Joris Timmermans

6
Um bom livro para procurar alogritmos? A maioria dos softwares é apenas CRUD simples, sem nada parecido com o que está incluído em qualquer curso ou livro de algoritmos.
Gilles

44
Teoria é sobre linguagens e algoritmos modernos. A prática é chegar ao trabalho no seu primeiro dia e receber a tarefa de adicionar um recurso menor ao software do ponto de venda em execução em uma caixa registradora que usa software que foi convertido manualmente do BASIC para o K&R C por pessoas que não conheciam C , usando um compilador de buggy de um fornecedor que faliu e espera-se que o recurso funcione até sexta-feira, o mais tardar.
Gort the Robot

Respostas:


61

Eu acho que a principal diferença é que, com a engenharia civil, a física do mundo real age como uma constante e poderosa verificação da realidade, que mantém a teoria sã e também limita as más práticas, enquanto na engenharia de software não há força igualmente forte para manter também conceitos práticos da torre de marfim como obra de má qualidade em cheque.

Muitos programadores tiveram más experiências com a teoria da fuga, tornando-se um impedimento ativo para que as coisas fossem feitas (por exemplo, "UML executável", processos de desenvolvimento super burocráticos). Por outro lado, hacks e patches sujos podem levá-lo muito longe, embora lentamente no final. E como você observa em seu último parágrafo: as falhas geralmente não são tão finais e, portanto, não são tão problemáticas.


11
Concordo com você que, na engenharia de software, é importante ter a quantidade certa de formalismo. Demais significa que você nunca pode começar e, talvez, quando descubra que cometeu um erro, seja tarde demais. Muito pouco significa que você pode fazer uma bagunça. Eu acho que você tem um ponto muito forte dizendo que produtividade e qualidade são muito mais difíceis de medir na engenharia de software do que na engenharia civil.
Giorgio

2
"... enquanto na engenharia de software não há força igualmente forte para manter impraticável ..." Acho que você quer dizer que não existe mais essa força. Naquela época, as limitações impostas pelos processadores mais fracos, menos memória e pouco / nenhum armazenamento agiam como uma força.
Blesh

11
@blesh: Acho que não. Limites apertados de hardware restringem igualmente a engenharia boa e a ruim.
Michael Borgwardt

Seus exemplos não são a teoria da programação. As restrições no software têm a ver com as tecnologias usadas e a capacidade matemática dos escritores.
Paul Nathan

5
Definitivamente, existe algo "teórico" sobre a UML ... ... sua utilidade!
precisa saber é o seguinte

29

Engenharia de software e engenharia civil têm pouco em comum. Os esforços de engenharia civil são limitados pelas propriedades físicas de seus materiais e pelo meio ambiente. Os engenheiros civis passam muito tempo aprendendo sobre as propriedades do solo e as características do material. O desenvolvimento de software é fisicamente limitado apenas pela velocidade dos processadores e pelo armazenamento disponível. Ambos são fáceis de entender e não gastamos muito tempo estudando-os. A principal limitação ao desenvolvimento de software é o intelecto humano. E não há dois desenvolvedores iguais. Esse código é sustentável? Por quem? Uma implementação de três linhas do quicksort em Haskell pode ser obviamente correta para alguns, mas incompreensível para outros. Uma equipe de dois pode preencher um requerimento em um mês, enquanto outra equipe de dez luta para entregar em um ano.

Desenvolvimento de software é todo design, os artefatos projetados são ordens de magnitude mais complexas do que qualquer artigo fabricado e cada um é único.


11
Concordo com suas observações de que o fator humano é muito mais forte em software, mas ainda assim, acho que tentar analisar um problema ou estruturar sua solução é uma atitude / ferramenta geral. Minha pergunta é por que alguns programadores acham que não é uma abordagem útil (ou mesmo uma perda de tempo). Você mencionou Haskell: Eu fiz um esforço para aprender alguns Haskell, embora não o usasse em nenhum projeto, porque pensei que me ajudaria a escrever um código melhor (mesmo em C ++ ou Java). Mesmo que eu não consiga medir isso, meu sentimento é que me tornei mais produtivo: faço mais coisas.
Giorgio

2
Um quicksort de três linhas da Haskell? Hmm ... é possível implementar o Quicksort em uma linguagem onde tudo é imutável por design?
Mason Wheeler

3
@MasonWheeler Primeiro resultado do Google: Quicksort em Haskell .
Chrisaycock #

3
@Mason: o tempo de execução ainda é O (n log n). Também requer memória O (n log n), ao contrário de uma classificação rápida no local, que requer apenas memória adicional O (log n) para a recursão.
Kevin cline

2
@kevincline Na medida em que um projeto de software típico é único, iniciei um projeto único na reforma do meu banheiro. A diferença é que, se eu estragar meu código, meus testes ficarem vermelhos e se eu estragar minha fiação, minha casa queimará. Obviamente, esse projeto também foi de horas extras e acima do orçamento, porque não tenho experiência em resolver problemas de remodelação. O principal problema que eu já vi em projetos de software é semelhante ... não é que as pessoas certas não possam resolver esses problemas mais rapidamente, é que as pessoas certas não estão disponíveis e temos que nos tornar as pessoas certas no mundo. voar.
Filodad

17

Como um engenheiro mecânico mais ou menos honesto (com alguns civis) virou programador, depois doutorado em CS (AI), professor e depois programador novamente (com licença, engenheiro de software ), eu tenho um discurso retórico sobre esse assunto geral.

Na engenharia tradicional

  • você precisa conhecer sua matemática e ciências, porque tudo que você faz é baseado nisso
  • os "heróis" no campo são pessoas que inventam coisas novas, descobrem novas idéias, resolvem problemas considerados insolúveis

Existe uma "física" que se aplica à teoria da informação de software, mas os engenheiros de software recebem pouca exposição a ela e certamente nada é aplicado. A maioria das teorias que obtêm é computabilidade e big-O.

Também fico continuamente impressionado com as pessoas que pensam que conhecer programação é suficiente e não precisam entender o assunto do programa.

Além disso, a inventividade não é incentivada. É desencorajado, a favor dos métodos de pensamento em grupo de denominadores menos comuns, disfarçado de "legibilidade". (Imagine se engenheiros aeronáuticos ou nucleares fossem incentivados a não fazer nada que pudesse ser difícil de entender para seus colegas juniores.)

O que eles aprendem, como programar aplicativos da Web, é de grande valor. O mesmo acontece com a habilidade de um encanador ou eletricista, mas não é de engenharia.


5
A física pode dizer se alguma estrutura entrará em colapso sob sua própria carga. O CS diz que você não pode dizer se um determinado programa será interrompido devido a uma determinada entrada. IMO métodos formais escala muito melhor em engenharia civil ou mecânica do que em software principalmente porque os sistemas são menos complexos e menos dinâmico ...
Guy Sirton

6
@GuySirton "O CS diz que você não pode dizer se um determinado programa será interrompido devido a uma determinada entrada." se isso é tudo que você pensa CS faz, eu acho que você pode não saber muito sobre como CS como você acha que fazer ...
gregghz

2
Cara, é incrivelmente improvável que você já tenha usado materiais de software que ninguém usava antes. McCarthy fez, e Turing, mas realmente, a engenharia de software não é tão incrível. Se estava tudo bem que o edifício caiu no fundo do oceano, porque você poderia simplesmente reiniciá-lo, que seria como engenharia de software.
Filodad

3
Eu daria a você um +1, exceto pela falha na legibilidade. A manutenção é 80% do custo do software, portanto a legibilidade não é uma questão pequena. Além disso, quando esse engenheiro aeronáutico ou nuclear estiver fabricando algo que será fabricado para que outras pessoas entendam que é importante. As instituições militares, governamentais ou mesmo grandes não estão felizes com uma invenção mágica que não pode ser replicada ou compreendida por ninguém além do inventor.
21464 Thomas

2
@ Thomas - A afirmação de que soluções viáveis ​​são freqüentemente descartadas com a alteração da "legibilidade" por mentes inferiores, não significa necessariamente que as soluções não sejam tão legíveis quanto deveriam ser. Eu já vi isso acontecer. Inferno, eu me peguei fazendo isso.
amigos estão dizendo sobre erik

13

Se eu fizer uma curva na maioria dos softwares e fizer algo que não é o melhor design, mas fará o trabalho, ninguém vai morrer. É a mesma razão pela qual uma cabana no jardim não precisa dos mesmos padrões de um prédio de 10 andares. No entanto, eu posso criar um aplicativo muito grande como o facebook, e se ele estragar e perder alguns dados, ou o que for, não é realmente tão grande assim. Também é mais simples consertar a base de um aplicativo grande após o fato, do que substituir a base de um edifício de 10 andares. Tudo se resume ao contexto e ao cálculo de riscos.

Também posso, com segurança e simplesmente continuar adicionando a um aplicativo. Você não pode arremessar facilmente em um novo terceiro andar de um prédio de 10 andares (11). Posso lançar um novo recurso para um aplicativo grande todos os dias, se eu quiser.

Agora, um bom design facilita tudo isso na programação. Mas não é impossível com um design ruim e os riscos, são ... software de buggy. Geralmente não é a morte.


Bem, você espero que eles não vão morrer ... depende do seu software;)
Rig

3
@ Rig, é por isso que eu disse 'mais' e 'normalmente'. Alguns softwares são muito mais críticos.
precisa saber é o seguinte

Eu acho que isso está se tornando um ponto muito ruim de vista, com certeza a maioria dos softwares não tem quaisquer implicações de segurança, mas não há dinheiro e privacidade envolvido em um monte de software, ficando estes errada também pode aterrá-lo em tribunal
jk.

11

Tenha paciência comigo nessa. Eu tenho razão.

Certa vez, um professor me disse que procrastinar leva a mais procrastinar, mesmo que a maioria das pessoas, depois de uma noite de trabalhos escritos / cheios de programação, digam a si mesmos: "Eu nunca farei isso de novo. Da próxima vez, vou começar cedo e terminar cedo ". Na minha experiência como procrastinador consumado, descobri que isso é verdade, e aqui está a explicação do professor: por mais desagradável que seja a experiência de procrastinar, na maioria dos casos, você acaba tendo um sucesso relativo. Esse é um comportamento de alto risco / alta recompensa. Depois de um tempo, você esquece todos os desagradáveis ​​e só se lembra da recompensa. Assim, a próxima tentação de procrastinar é ainda mais atraente, porque você conseguiu a última vez.

Eu acho que uma analogia pode ser feita aqui com a técnica de programação "faça as coisas" que vemos com muita frequência. Um programador ou equipe de programadores, talvez por ignorância, preguiça ou talvez por uma restrição de tempo genuína, adota a abordagem "fazer as coisas" à programação, jogando toda a sua teoria, matemática e boas práticas pela janela. E sabe de uma coisa? Eles fazem as coisas. Não é elegante, bonito ou sustentável, mas faz o trabalho. Talvez um superior não técnico que não conheça um ponto-e-vírgula de um semáforo os elogie por "fazer as coisas". Assim, na próxima vez em que o programador for tentado a adotar essa abordagem superficial da programação, é tudo mais fácil, porque, ei, funcionou da última vez, não foi? É a saída "fácil", a menos que você seja pobre,

Eu tenho uma alma pobre e infeliz, e muitos de vocês provavelmente também. Eu imploro a todos vocês. Não tome o caminho mais fácil! :)


3
Se você tiver que fazê-lo uma vez e esquecer, está tudo bem. Mas se você precisar estendê-lo e mantê-lo posteriormente, estará procurando problemas. Você precisa ter uma noção da quantidade de teoria: muito significa que você nunca fará isso, muito pouco significa que fará 10 vezes antes de realmente fazer. Meus 2 centavos.
Giorgio

6
Mas, às vezes, você precisa disponibilizar seu software agora . Você precisa vencer um concorrente no mercado. Ou você tem um requisito legal para fornecer algumas informações. Ou você só precisa obter um fluxo de caixa para continuar existindo quando a bagunça que você fez na sua abordagem "faça o trabalho" for um problema ... o que às vezes é um bom problema. Porque se você não o tiver, não será liberado a tempo e sua empresa estará morta antes de começar.
CaffGeek

11
@ Chad - eu concordo com você. É um equilíbrio. Todas as coisas que você menciona se enquadram em "uma restrição de tempo genuína" como motivos para a programação de execução e, a curto prazo, é bom e até vantajoso quando você o faz.
68650 FishBasketGordo

@FBG: Disse brilhantemente.
Kubá Ober1

@ Chade, bom ponto. Martin Fowler faz uma observação semelhante em martinfowler.com/bliki/TechnicalDebt.html . Às vezes, é uma troca que vale a pena.
John M Gant

9

Sua premissa é falho. A principal razão pela qual os engenheiros civis usam a engenharia ao projetar grandes edifícios, pontes, túneis etc. é garantir que eles estejam usando uma quantidade mínima de material (concreto, aço estrutural etc.) que atenda aos padrões de segurança exigidos. É perfeitamente possível construir um edifício alto sem muito em termos de matemática (por exemplo, as pirâmides das antigas civilizações egípcia e maia) se os custos de material e de mão-de-obra não forem objetos, mas uma vez construídos, geralmente não há sentido em modificar para fazê-los usar o material com mais eficiência.

Existe uma dinâmica um pouco diferente no design de grandes sistemas de software. Na verdade, eles geralmente são mal projetados, mas isso ocorre porque o design pode ser alterado dinamicamente à medida que o trabalho avança, o que simplesmente não pode ser feito com tanta facilidade em projetos de engenharia civil.

O fator comum é o custo. O design de um projeto tradicional de engenharia civil reduz os custos (reais, em termos de material e potencial em termos de responsabilidade), enquanto chega um ponto no desenvolvimento de software em que o custo do design aumenta além do valor retornado.


"chega um momento no desenvolvimento de software em que o custo do design aumenta além do valor retornado.": escrevi explicitamente "a quantidade certa de teoria". Eu sei que o excesso de engenharia não aumenta a produtividade.
Giorgio

Existem quase zero projetos da IMO que são projetados com antecedência e que realmente seguem seu design. A engenharia civil está (geralmente?) Construindo a mesma coisa repetidamente (uma estrada, uma droga, um túnel, um prédio, uma ponte). As técnicas são bem conhecidas. Isso não é verdade no software. Porque pode ser mudado facilmente e porque as pessoas não sabem o que querem ou o que funciona até que tentem um projeto sério com antecedência, é uma perda de tempo. Nós construímos, testamos e iteramos. Algo que não é possível com a Engenharia Civil, como apontado acima. As 2 disciplinas não são comparáveis.
gman

5
Desculpe, preciso apontar o erro de digitação: não acho que engenheiros civis construam nada. ;-)
Giorgio

2
Eu imagino que no futuro, quando nós, engenheiros de software, criarmos um software legal de simulação de engenharia civil, os engenheiros civis poderão acabar com todo esse material matemático. Basta construir um arranha-céu virtual de 10 km de altura. Se ele não cair sob seu próprio peso nos primeiros 100 anos virtuais e puder suportar um furacão virtual cat 5, use a impressora 3D de arranha-céu especial para construí-lo.
Emory

11
@RexKerr: você cortou metade de sua declaração: "... que satisfaz os padrões de segurança exigidos"
Lie Ryan Ryan

7

Eu também apontaria, além de várias outras excelentes respostas, que a humanidade tem feito o equivalente à "engenharia civil" desde os tempos dos egípcios com facilidade, por isso tivemos muito tempo para aperfeiçoar a teoria geral de como as coisas deveriam acontecer. ser feito. Estamos construindo software há cerca de 70 anos (dependendo do que você considera o primeiro "software"); Quero dizer que não tivemos a mesma quantidade de tempo para desenvolver o mesmo tipo de corpo de experiência.


6

As plantas de um arquiteto / engenheiro civil praticamente nunca são idênticas aos planos "como construídos". Algo SEMPRE muda. Por quê? Porque existem e sempre haverá "incógnitas desconhecidas". Existem coisas que você sabe e pode planejar, coisas que você sabe que são desconhecidas e que você pode pesquisar e estimar; e outras que você não sabe que não sabe; "surpresas". Você pretende eliminá-los na maioria dos sistemas aprendendo tudo o que pode, mas basta uma pequena violação do código de construção (que pode ser baseada em uma regra que não existia há 2 anos quando seu prédio estava sendo conceituado) e tudo - o plano diretor abrangente precisa mudar, às vezes de maneira bastante drástica.

Software é muito parecido com isto; sempre há um desconhecido desconhecido. No entanto, diferentemente da engenharia civil ou estrutural, o desenvolvimento de software é inerentemente muito mais tolerante à mudança com base nos problemas que as incógnitas desconhecidas criam. Se você está construindo um prédio de 10 andares e superestimou a capacidade de carga da fundação que colocou em seu projeto, você não pode construir o prédio em 10 andares ou precisa extrair uma quantidade significativa de trabalho para volte para a fundação e a reforce ou reconstrua. No entanto, no software, se você subestimou as demandas de uma camada específica da estrutura geral da solução, há muitas opções para corrigir essa camada que não envolvem a invalidação de todo o outro trabalho. Você pode substituir um único servidor de banco de dados por um servidor mais poderoso ou um cluster de replicação / failover, ou um cluster de balanceamento de carga / distribuído. O mesmo para o servidor da web. Se você codificou um algoritmo que é ineficiente, mas simples, com base em suposições incorretas do tamanho da entrada, quase sempre é possível simplesmente remover e reescrever a implementação de maneira relativamente cirúrgica, sem afetar outro código que tenha conhecimento do algoritmo (chama e passa a entrada para ou espera uma saída dele).

Essa relativa facilidade de mudança permite que um engenheiro de software codifique com base no que sabe, sem se preocupar indevidamente com o que não sabe. Isso permite a aplicação mais lenta da teoria e do projeto conceitual inicial; você mergulha e o faz, e ao longo do caminho encontra as coisas que codificou que precisam mudar e as muda. Você ainda deve conhecer os conceitos e a teoria, porque quando um problema é descoberto, são essas coisas que o ajudarão a identificar a causa e a criar uma solução. Mas você pode tomar uma decisão rápida sem sucumbir à "paralisia da análise", porque se você tomar a decisão errada com base em algo que você não sabia ou não considerou seus "cálculos", o erro é mais fácil de corrigir.


3
Também há muito mais incógnitas desconhecidas no desenvolvimento de software - você pode começar construindo um arranha-céu, mas quando o cliente olha para ele, ele diz "na verdade eu queria um cubo de Rubix com dez andares de altura".
Tacroy

@Tacroy: Curiosamente, um engenheiro civil provavelmente consideraria este um cliente ruim que está desperdiçando seu tempo e recursos; um engenheiro de software tentará desenvolver uma nova metodologia para satisfazê-lo. :-)
Giorgio

11
@Giorgio, ou projeto de lei nesse sentido ...
CaffGeek

5

A diferença é principalmente devido aos requisitos conhecidos:

  • No lado da teoria, tudo é definido com antecedência, para que você possa saber exatamente o que precisa antes de começar.
  • Na prática, eles geralmente não estão todos lá, ou você descobre algo no meio da implementação que faz com que você precise reprojetar algo. Portanto, é muito melhor começar com pelo menos desenhos rudimentares, para que você possa descobrir esses problemas desde o início.

Além disso, quando se fala de "teoria", geralmente significa o lado da teoria da ciência da computação, em vez de engenharia de software. Essa é a parte da ciência da computação que trata principalmente de encontrar algoritmos melhores e mais eficientes, provando se algo é ou não possível (P e NP, por exemplo) e assim por diante. Embora seja bom ter isso em mente, eles não surgem no desenvolvimento de software com muita frequência.

Usamos bibliotecas para esse tipo de coisa, tanto quanto possível.


11
+1 para "quando se fala de 'teoria', geralmente significa o lado da teoria da ciência da computação".
18730 Joshua Drake

5

Na verdade, existem alguns níveis de engenharia de software, dependendo do que o software que você está construindo está fazendo.

A NASA precisa de um software para controlar ônibus espaciais no espaço, de modo que o nível do processo de engenharia é muito mais rigoroso do que o de criar um site para mostrar imagens de foguetes.

Um de meus colegas de trabalho que trabalhou para a NASA descreveu anteriormente seu processo de engenharia de software como escrevendo centenas de páginas de justificativa e centenas de horas de reuniões para justificar a escrita de uma única linha de código!

Não me entenda mal, porque não estou tentando parecer desrespeitoso quando digo isso, mas mesmo depois de todo esse custo de tempo, recursos e bilhões de dólares, o ônibus espacial ainda explodiu.

Até os engenheiros civis sabem que, não importa quanta teoria eles colocam em um projeto, algo acabará por quebrá-lo; portanto, eles também precisam desenvolver planos de contingência.

Ao criar um software, o custo do travamento raramente causa perda de vidas, por isso é muito mais fácil lançar rapidamente as coisas e testá-las. Vamos concordar que fazer as coisas rapidamente resulta em código fraco. Mesmo que esse seja sempre o caso, ver o software em ação é a melhor maneira de um desenvolvedor ver onde é fraco e precisa ser fortalecido versus onde é fraco e ainda muitas vezes mais forte do que o necessário para acompanhar A carga.

Para resumir, Premature optimization is the root of all evil ou como meu chefe sempre diziaShipping is a feature!


3
+1 para "O envio é um recurso"! Certa vez ouvi uma frase semelhante: "A perfeição não existe. Este software tem a vantagem de existir". Claro que é uma piada. Em relação ao software de missão crítica: uma exceção não capturada pode causar um foguete.
Giorgio

this software has the advantage that it exists... eu não tinha ouvido falar ainda, mas ele está entrando na minha lista de ótimas citações de software. eu gosto
Albert Lang

@Giorgio: JSF e MISRA C são escritos para que não haja exceções. Exceções e foguetes não se misturam.
Coder

5

Muitas respostas boas aqui, mas acho que a comparação entre Ciência da Computação e Engenharia Civil é falha.

A rigor, o que os desenvolvedores profissionais de software fazem é mais como Engenharia de Software do que Ciência da Computação. Uma analogia melhor é que a Ciência da Computação é a Física para Engenharia de Software. Da mesma forma, a Engenharia Civil é uma coleção de simplificações e aproximações da Física para praticamente construir coisas.

Imagino que os Engenheiros Civis raramente tenham que levar em consideração a relatividade geral ao realizar seu trabalho. Grande parte da Engenharia Civil pode ser construída com segurança na Mecânica Newtoniana. Da mesma forma, a Engenharia de Software pode ser realizada com muito sucesso, com uma compreensão aproximadamente aproximada da ciência da computação teórica.

A grande diferença é que pontes, arranha-céus e outros produtos da engenharia civil são coisas razoavelmente bem compreendidas. Os engenheiros de software costumam criar novas construções ou usar métodos novos para criar coisas bem compreendidas. A engenharia de software é MUITO menos madura que a engenharia civil, e isso provavelmente continuará a ser verdade no futuro próximo.

TL; DR : Teoria e prática são diferentes na Engenharia de Software, assim como em qualquer outro lugar. A analogia adequada é Engenharia de Software: Engenharia Civil :: Ciência da Computação: Física. Mas, na prática, é um pouco mais complexo que isso :)


"Eu imagino que os engenheiros civis raramente precisam levar em conta a relatividade geral quando realizam seu trabalho. Grande parte da engenharia civil pode ser construída com segurança na Mecânica Newtoniana.": Até onde eu sei, eles precisam usar bastante cálculo (integrais). e coisas assim). Isso não é mecânica quântica, mas o IMO é definitivamente não trivial.
Giorgio

2
Claro, mas você não precisa derivar uma equação de onda para cada componente da sua ponte e depois explicar como eles interagem.
precisa saber é o seguinte

Você está certo. No entanto, meu argumento não é quanta teoria é usada na engenharia civil e na engenharia de software. Em vez disso, os engenheiros civis sabem que precisam usar suas fórmulas e fazer cálculos sobre como construir algum edifício. Na engenharia de software, tenho a impressão de que há mais improvisação e, às vezes, se você quer se sentar e analisar um problema (apenas para acertar, não para escrever uma tese de doutorado), pode ser desaprovado: queremos entendê-lo terminado, para não torná-lo perfeito. Mas alguma teoria da OMI (não muito) é exatamente o que pode ajudar a finalizar mais rapidamente!
Giorgio

Você precisa encontrar um ponto de equilíbrio apropriado para o seu projeto. Os desenvolvedores juniores são tipicamente mais entusiasmados em juntar porcaria para ver o que vai ficar. Se eles vieram de uma base muito teórica, podem até ter idéias mais loucas e excessivamente complexas. Gerenciar desenvolvedores juniores de maneira eficaz envolve frequentemente ajudá-los a dar um passo atrás e analisar seu trabalho. Por outro lado, os desenvolvedores seniores podem se concentrar demais em questões de design de longo prazo, a ponto de terem problemas em se concentrar nas necessidades imediatas.
precisa saber é o seguinte

Uau, desculpe, este tópico está fora de tópico, mas sem ler sua resposta, terminei exatamente o mesmo - com um TL; DR e, literalmente, exatamente a mesma analogia. Formato SAT. Eu o editei da minha resposta para que não pareça que estou copiando você, mas ainda está me assustando. Talvez os programadores pensem demais.
Jarsen

3

Então, minha pergunta é por que alguns programadores pensam que existe um contraste entre teoria (métodos formais) e prática (fazer as coisas)?

Construir software é diferente de construir uma ponte. No software, existem muitos objetos a serem construídos que podem ou não ser definidos no início. Existem padrões para aumentar a facilidade de manutenção e colaboração do desenvolvedor, para não aderir a fórmulas matemáticas arbitrárias ou outros ideais. Por exemplo, ao selecionar o comportamento com base em uma variável, às vezes faz sentido usar um comutador, outras vezes, um padrão de fábrica. Depende da facilidade de manutenção e dos pontos de dor identificados, como problemas de desempenho.

Outro exemplo pode ser feito com a manipulação de dados. Geralmente, faz sentido usar delegados no contexto do .NET. Não é tão fácil em Java porque não possui o suporte de estrutura para o estilo de programação funcional que o .NET possui. Em outras palavras, no caso geral, simplesmente não é possível executar X na situação Y. Isso se deve ao fato de X e Y dependerem do número N de fatores variáveis.

A engenharia de software (software de construção) é percebida por muitos como fácil em comparação com, digamos, a engenharia civil (construção de casas)?

Não sei se "fácil" é o termo correto. A falta de evidências tangíveis pode levar à percepção de que nenhum trabalho está sendo realizado. Ou, da mesma forma, o trabalho existente é facilmente alterado.

Ou essas duas disciplinas são realmente diferentes (além do software de missão crítica, a falha de software é muito mais aceitável do que a falha de construção)?

Engenharia tradicional e engenharia de software são muito diferentes pelas razões que já afirmei.


1

Sua percepção pode estar errada aqui, ou inclui muitos recursos de pessoas que não escreveram software suficientemente complexo.

Sua experiência está alinhada com o que a maioria das pessoas que eu conheço (que criaram e criaram software suficientemente complexo) diria.

Dito isto, quando se trata da maioria dos programadores , quando a tarefa de escrever algo chega até eles, o design ("a matemática", como você disse) já foi feito pelo arquiteto / lead / etc. antes que a tarefa de escrever chegue até eles. Portanto, pode parecer assim a partir do nível da linha de frente.


3
"the maths ... já foi feito": não apenas, considere todas as funções da biblioteca, estruturas, DBMS, protocolos e toneladas de outras coisas pesadas que podemos usar em nosso código chamando uma função com alguns parâmetros. Como programador, às vezes me sinto mais como o trabalhador que anda no cadafalso do que como o engenheiro que projetou o edifício.
Giorgio

1

Eu acho que a razão desse contraste é que o ciclo de vida de um projeto de software e um projeto de hardware ou arquitetura é diferente. A maioria dos softwares evolui gradualmente, não é planejada do começo ao fim. Os desenvolvedores de software podem aplicar uma abordagem iterativa ao desenvolvimento: planejar, implementar e ouvir comentários. Se o feedback for positivo, continue, não - dê um passo atrás e reconsidere sua estratégia. É por isso que os desenvolvedores de software têm coisas como desenvolvimento ágil, produto mínimo viável e assim por diante.

Os engenheiros civis não têm esse luxo. Para eles, uma vez que algo está planejado, você não pode alterá-lo tão facilmente, como no software, porque o custo dessas mudanças pode ser terrível. Para o desenvolvimento de software, por outro lado, não custa muito, e isso pode ser usado para sua vantagem.

Mas nem todo ramo de desenvolvimento de software pode se permitir essa abordagem. A criação de software, por exemplo, para aviação ou serviços médicos exige um planejamento muito cuidadoso e muitos cálculos anteriores.


1

Parece o mesmo para mim. Você constrói um edifício grande com blocos padrão, concreto de resistência padrão, aço padrão. Você cria um grande aplicativo a partir de bibliotecas padrão.

Você não tenta matematicamente formalmente provar que um aplicativo grande está correto da mesma forma que não tenta escrever a função de onda para um edifício de 100 andares


Então, qual é o software equivalente a uma análise de elementos finitos do edifício de 100 andares? Quantos prédios altos têm bugs no therm / crash? :-)
Guy Sirton

@GuySirton - você só pode analisar um prédio grande em um nível muito grosseiro, com menos detalhes do que faria em um aplicativo típico. Muitos edifícios grandes apresentam falhas, janelas caem, passagens desmoronam e criam efeitos de túneis de vento. Ou no caso de um hotel curvado e altamente reflexivo em Las Vegas, você cria um raio da morte na piscina!
Martin Beckett

Você pode obter uma granulação bastante fina na FEA e prever o comportamento com um grau muito alto de precisão. As pessoas ainda cometem erros. Para a OMI, é simplesmente impossível fazer previsões semelhantes em um software complexo. As falhas mencionadas são uma fração minúscula do número total de edifícios. As taxas de defeitos no software devem ser duas ordens de magnitude mais altas. Dito isto, é obviamente um continuum entre onde métodos formais são úteis e onde são inúteis.
Guy Sirton

@ BuySirton - Eu acho que a dificuldade é que você confia em outras coisas. A Nasa pode testar aviônicos de vôo em um nível muito detalhado (embora ainda não prove que esteja correto), porque eles também criam o sistema operacional e o hardware. Escrever em um sistema operacional geral com kits de ferramentas e bibliotecas é como construir uma ponte onde você não tem permissão para conhecer os detalhes do aço ou do concreto.
Martin Beckett

11
@MartinBeckett, e o coeficiente de gravidade muda aleatoriamente de hora em hora ... como quando o administrador do sistema decide atualizar um servidor aleatoriamente, sem atualizar ninguém, sem dizer a ninguém, porque "será transparente".
CaffGeek

1

Eu era engenheiro mecânico e de manufatura antes de descobrir, há 20 anos, que minhas aptidões estavam em software. Simpatizo com muitos dos elementos que você expôs.

Suspeito que a verdadeira natureza do problema seja sobre como fazemos as coisas. Agora temos mais ou menos dez anos de desenvolvimento ágil sob nossos cintos coletivos, e a mensagem é clara. Não progrida por camadas; progresso por recursos. Claro - haverá projetos quando você precisar progredir por camadas (por exemplo, construir sua pilha de rede antes do servidor da web), mas para a grande maioria dos projetos do mundo real, aprendemos a lição de que, ao oferecer recursos de trabalho, um ou alguns em uma vez, é muito mais eficaz a construção de grandes teorias não testadas e a tentativa de implementá-las.

Então, vamos pegar o exemplo da sua cabana (eu costumo falar em fazer uma ponte lançando um log através de um fluxo versus uma ponte suspensa de um quilômetro de comprimento ... tanto faz!) E trazê-lo ao mundo da engenharia de software. A principal diferença que vejo é que, em software, a maior parte do trabalho é de uma escala que não precisa de uma grande modelagem inicial para ter sucesso. O erro do iniciante geralmente é assumir que as coisas precisam mais disso do que realmente são, e para a maioria de nós, depois de cometê-lo algumas vezes, tentamos repeti-lo com muita frequência.

Não há argumento - existem projetos que precisam começar com um comitê de 17 arquitetos de software. Na verdade, eles são tão raros quanto 20 diamantes de quilates.


1

Eu acho que a analogia é falha. Até onde sei, a engenharia civil não possui o mesmo tipo de base teórica que a ciência da computação; a ciência da computação nasceu da matemática teórica - como as máquinas de Turing. Engenharia civil é criar estruturas que resistem à mãe natureza e talvez até sejam bonitas. Novamente, eu realmente não sei muito sobre engenharia civil, mas acho que não há equivalentes de engenheiro civil entre P vs NP, o vendedor ambulante e outras coisas divertidas contra as quais você deve se basear. Definitivamente, existe um lugar para a nossa teoria da ciência da computação - se alguém resolver o vendedor ambulante ou o problema de interrupção que estamos enfrentando para obter muitos avanços impressionantes. Mas para um engenheiro de software, cujo negócio é arquitetar software, esses problemas são realmente apenas divertidos e jogos.

Agora, também acho que depende do que você quer dizer com "teoria". Estamos falando de padrões de design ou de um lema de bombeamento? Porque ter um bom entendimento sólido dos padrões de design é absolutamente essencial para ser um bom engenheiro de software. No entanto, ao arquitetar um grande sistema de software, teorizar sobre problemas de P / NP não é útil. Nesse sentido, acredito que exista um contraste muito forte entre engenharia de software e ciência da computação teórica.

Ou a teoria se refere a algoritmos? Você não gasta muito tempo escrevendo algoritmos que aprendeu na sua classe de algoritmos. Por quê? Como você normalmente só precisa deles em casos específicos (e depois pesquisa e pesquisa), ou usa uma biblioteca já escrita para você. Não há necessidade de escrever outro classificador bayesiano. A abstração é um princípio importante na ciência da computação. Eu acho que os engenheiros de software tendem a não aprender como um algoritmo funciona até que precisem.

Outro motivo é que atualmente existem vários métodos populares de desenvolvimento de software que são eficazes. Por exemplo, no desenvolvimento ágil, você não arquiteta um sistema inteiro antes. A razão para isso é que você ainda não sabe exatamente o que está construindo - deseja que o que está fazendo seja flexível e se adapte às novas informações e requisitos. Projetar tudo desde o início e criar apenas isso nem sempre produz o melhor software. No entanto, não é a solução para tudo. Por exemplo, digamos que você esteja criando uma coisa nova louca por computação distribuída. Você não pode fazer alguns esboços de guardanapos e iniciar seu SCRUM.

TL; DR. Eu acho que há algum equívoco em torno da palavra "teoria". Tradicionalmente, a teoria se refere aos aspectos matemáticos teóricos da ciência da computação. A menos que você esteja pesquisando novas formas de computação, a maior parte da ciência da computação teórica não participa do dia-a-dia de um engenheiro de software. Os engenheiros de software se preocupam com os padrões de design e a arquitetura do sistema. Detalhes de implementação específicos de determinados algoritmos não são importantes. Muitas vezes, com idéias menos complicadas, é apropriado não criar muito e apenas começar a codificar. E acho que é daí que surge a idéia de que os programadores não gostam de teoria.


11
Vejo algumas semelhanças entre nossas respostas, mas suas idéias são obviamente originais e há algumas diferenças. Não concordo que entender P / NP não seja útil. Você não precisa estudar profundamente a Teoria da Complexidade, mas um engenheiro de software em funcionamento deve ser capaz de estimar o O (n) de qualquer parte do código e dizer coisas inteligentes sobre o custo de soluções alternativas. Um ponto que você quase fez, mas não fez, é que a teoria é frequentemente encapsulada em bibliotecas. Essa é uma boa a considerar.
precisa saber é o seguinte

"Se alguém resolver ... o problema que está travando, temos muitos novos avanços impressionantes.": Infelizmente, a teoria provou que isso é insolúvel (não existe um programa que possa decidir isso), então eu não acho que esforços de pesquisa estão sendo gastos tentando resolver o problema da parada.
Giorgio

Máquinas de Turing não podem "No entanto, nem todas as máquinas concebíveis para a imaginação humana estão sujeitas à tese de Church-Turing ... É uma questão em aberto se pode haver processos físicos determinísticos reais que, a longo prazo, iludam a simulação por um Máquina de Turing e, em particular, se algum desses processos hipotéticos poderia ser útil na forma de uma máquina de calcular (um hipercomputador) que poderia resolver o problema da parada ... Também é uma questão em aberto se algum desses processos físicos desconhecidos está envolvido em o funcionamento do cérebro humano ... "- Problema de Halting, Wikipedia
Jarsen 06/06/12

Então, até onde sei, e me corrija se estiver errado, acho que ainda temos muitas descobertas a serem feitas sobre computação. Como já foi mencionado várias vezes neste tópico, a ciência da computação ainda é muito jovem; poderia haver muito além da Turning Machines e da arquitetura Von Neumann.
21412 Jarsen

@Jarsen: É verdade que a ciência da computação é muito jovem, mas qualquer computador que foi construído até agora só pode fazer coisas computáveis ​​em Turing. Até onde eu sei (muito pouco mesmo), mesmo computadores quânticos não podem fazer mais (eles poderiam resolver certos problemas mais rapidamente, mas não seriam capazes de resolver mais problemas). Então, sim, quem sabe o que pode ser inventado, mas qualquer formalismo computacional que foi imaginado nos últimos 70 anos não pode fazer mais do que uma máquina de Turing.
Giorgio

1

A diferença entre teoria e prática é muito grande no momento. Ao fazer a teoria, você recebe três axiomas e é subseqüentemente mostrado que um teorema de uma linha tem uma prova de mil páginas ou nenhuma prova. Na engenharia de software, você recebe APIs inconsistentes de milhares de funções, que oferecem inúmeras maneiras (ruins) de implementar um recurso subespecificado.

A engenharia de software real enlouquece a maioria dos que estão no campo formal, e o desenvolvimento de software matemático real enlouquece os que estão na engenharia. Ambos os campos exigem pessoas com diferentes aptidões, e não acho que as aptidões se sobreponham com frequência.


0

A teoria formal pressupõe que você possa planejar com precisão tudo com antecedência, como um produto fabricado, que o software existirá indefinidamente no mesmo ambiente e que resolver um problema abstrato geral é sempre o objetivo. Ele pressupõe um ciclo de vida de software como produto 4D: projetar, desenvolver, implantar, pronto. A teoria formal trata de resolver o problema do design de software usando análise, abstração, generalização e previsão de mudanças futuras. Isso é bom se você tiver um problema bem definido em um domínio direto que seja facilmente analisável, previsível e bastante estático.

A programação prática trata da solução do problema certo (não do design de software) da maneira certa agora, para que seus colegas de trabalho possam fazer seu trabalho melhor / mais rápido / de todo, ou para que as receitas possam fluir para a empresa. Muito do software não é como um produto, nunca 'pronto', mas mais como um ser vivo, que começa altamente especializado em um nicho ecológico e pode ter uma vida útil amplamente variável, durante a qual ele precisa resolver problemas novos e imprevistos de uma vez. ampla variedade de ambientes em constante mudança. No mundo dos negócios, com políticas e legalidades, concorrência e organizações, estruturas e tendências em constante mudança, os requisitos são muitas vezes ambíguos, complicados com todos os tipos de casos especiais, mal definidos e sujeitos a rápidas mudanças inesperadas. Eles não são analisáveis, previsíveis ou estáticos, e muitas vezes não é lógico ou razoável. É provável que o software seja irrelevante em 2 semanas e permaneça em uso em 20 anos. Ele vem ao mundo sem saber muito ou capaz de fazer muito, e precisa ser nutrido, preparado e treinado ao longo de sua vida para crescer forte, flexível e capaz de se adaptar a seus ambientes em constante mudança e novos problemas. Se você a negligenciar após o nascimento, ela ficará selvagem se sobreviver por tempo suficiente e causar dor e sofrimento, resolvendo problemas com força contundente.

A teoria formal não atende às necessidades de muitos softwares de negócios do mundo real. Isso nos leva a acreditar que o software pode ser projetado e executado. Que é um produto que pode ser fixado ocasionalmente, polido ou ter itens presos, mas não um ser vivo que precise ser criado adequadamente com cuidado e atenção constantes ao longo de sua vida útil. Então, acabamos com um código legado feroz, realmente feio, mas a teoria formal provavelmente não teria ajudado nisso.

Tudo isso parece bastante negativo, mas, na realidade, eu amo usar a teoria formal. Um design bonito sempre traz um sorriso ao meu rosto. No entanto, isso é principalmente na minha programação amadora que não está sujeita às vicissitudes dos negócios. No trabalho, lido principalmente com o código orgânico e espero poder dar atenção suficiente para que ele cresça corretamente, me deixe orgulhoso e não seja desagradável e rude com outras pessoas que precisam lidar com isso.


0

As apostas são mais baixas, o trabalho é mais fácil e a gerência raramente vê o valor em um bom design. Instabilidade, manutenção e integridade do sistema são um problema de "TI" - não um problema de "negócios". Todos os executivos têm uma coisa em comum. Eles são 95% focados em dinheiro ou se reportam a alguém que é.

O resto da batalha é com seus colegas programadores. Muitos deles não podem ou não se comprometem a pensar em um problema antes do início da codificação. Devido ao exposto, muitas dessas pessoas são desenvolvedores seniores, tornando ainda mais difícil obter um bom design para produção.

Eu assisti a projetos liderar anos perdidos adicionando recursos e correções ad-hoc a projetos que eram difíceis de começar, e depois abater todas as tentativas de trazer ordem ao caos com frases como "muito complicado" ou "perda de tempo". Não é agradável assistir a um grande projeto em espiral até seu destino inevitável, porque a administração não admite que está construindo sua própria prisão diariamente; no entanto, temo que seja uma realidade infeliz que muitos desenvolvedores tenham testemunhado e - para melhor ou pior - aprendido.

Eu tento encontrar um meio no meu trabalho. Não vos escrevo mais código em projetos de "contaminado" do que o absolutamente necessário, e eu aproveitar todas as oportunidades para mover a funcionalidade fora deles. "Entre projetos", dedico tempo ao design e limpeza dos projetos sobre os quais realmente tenho controle.

No final, é uma grande bagunça de política e integridade pessoal que 75% dos programadores do mundo não têm estômago. Eu mal posso suportar isso sozinho.


0

Primeiro de tudo, eu amo essa pergunta. Eu escrevi três respostas de 1000 palavras e elas estavam terrivelmente erradas quando cheguei ao fim delas.

O problema de tentar comparar os dois como análogo, eu acho, é que a programação é um processo de modelagem que pode ser tão abstrato ou fortemente ligado ao concreto quanto você quiser.

A teoria da engenharia estrutural, por outro lado, está fortemente ligada a conjuntos muito específicos de leis baseadas na realidade com as quais você deve se conformar. Você não pode simplesmente alterar o contexto ou as leis. O problema em si está enraizado nessas leis. Na programação, no entanto, às vezes a solução está realmente alterando a natureza da questão ou simplesmente colocando-a em um contexto diferente.

Se o padrão MVC, por exemplo, é um ajuste perfeito, tem muito a ver com esse contexto. Um aplicativo de desktop normalmente lida em um idioma e apenas um idioma, sem contar os arquivos de configuração.

O front end de um aplicativo Web, por outro lado, consiste principalmente em duas linguagens declarativas (não programadas) e JavaScript. A única coisa física que você não pode abstrair totalmente é o fato de que sempre existe esse mural http para colocar as coisas entre o servidor e o navegador. Independentemente de como você o enterra no código, isso leva tempo e design assíncrono.

Obviamente, você não pode usar um padrão popular e bem conceituado como o MVC para lidar exclusivamente com as preocupações de front-end na Web sem alterar a maneira como você pode lidar com isso no contexto de um aplicativo de desktop. Na verdade, eu diria que você deve estar ciente do que torna o MVC útil, mas nem mesmo tentar implementá-lo de maneira particularmente exata ou abrangente. O paradigma de aplicativo da web é único, pois todo o material que é visualizado por mim é tratado pelo navegador do usuário e todo o material de dados / modelização normalmente está no servidor em algum lugar. Mas onde isso deixa o controlador? Tudo no servidor ou tudo no front-end? Alguém tem que possuir isso. Ou talvez o MVC não seja 100% o melhor para o cenário. Não é um ajuste adequado para o back-end do .NET. Não é terrível no contexto de widgets específicos da interface do usuário.

Construir uma casa resolve um problema. Problemas típicos de programação, no entanto, geralmente envolvem a solução de problemas dentro dos problemas e, às vezes, a solução é redefinir o problema externo. Infelizmente, a realidade não gosta muito dessa ideia.


0

Glenn Vanderburg apresenta uma excelente visão sobre as diferenças entre a engenharia de software e as disciplinas mais tradicionais de engenharia: http://www.youtube.com/watch?v=NP9AIUT9nos

Se um engenheiro civil pudesse testar seus projetos sem nenhum custo antes de construir a última coisa, faria muito menos uso da teoria. Se em segundos ele pudesse construir uma ponte mil vezes de graça para testar quando ela se romperia, ele o faria em vez de passar meses calculando quando isso poderia quebrar na teoria ...

No desenvolvimento de software, é exatamente isso que você faz. Em vez de calcular a rapidez com que o algoritmo é, em teoria, você pode testá-lo e saber a resposta em segundos.

De fato, a maioria dos softwares hoje não está mais limitada por restrições físicas, como poder de computação ou memória. A limitação do software é a complexidade que resulta em sistemas cada vez maiores. É gerenciar essa complexidade, mantendo o sistema compreensível pelos seres humanos, o que faz o enorme desafio na programação atual.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.