Os engenheiros de software realmente precisam saber mais coisas de baixo nível? [fechadas]

23

À medida que as linguagens de programação de alto nível, como C #, Java etc., estão se desenvolvendo, muitas pessoas afirmam que serão uma alternativa às linguagens como linguagem assembly e C / C ++, o que fornece acesso e controle ao hardware do computador, porque os programadores devem se concentrar na criação do programa e na solução de problemas, não perdendo tempo lidando com o computador para fazê-lo funcionar. À medida que o hardware continua melhorando, a diferença de desempenho entre C / C ++ e Java não será significativa, e os grandes jogos poderão ser programados em uma linguagem como Java.

Essa é a ideia geral que resumi brevemente depois de examinar esse tópico na Internet. Você acha que isso se tornará real no futuro próximo? Isso significa que tudo o que aprendemos sobre coisas de baixo nível não é mais prático para a indústria de software? Isso significa que a linguagem assembly e C / C ++ se tornarão relevantes apenas para engenheiros elétricos, uma vez que seriam os únicos que precisam programar seus componentes elétricos?


Quanto aprendizado é suficiente? Se aprendermos coisas demais de baixo nível, eventualmente nos tornaremos mais orientados em engenharia elétrica ou se aprendermos muita matemática, poderemos estar aprendendo a nos tornar matemáticos, não programadores. Eu só quero saber se os materiais de matemática que aprendi (fiz um curso de matemática que cobre o material semelhante a este livro (eles usavam livros diferentes): Matemática discreta e sua aplicação) são realmente tão úteis quanto nosso conjunto de habilidades de programação. Muitos exercícios de matemática podem levar a maioria de nós horas para fazê-lo, e se você for sério com isso, terá menos tempo para estudar programação. Em nosso fórum gamedev, até mesmo Matemática e Física têm apenas uma seção para comparar com as de programação.

No momento, comecei a ler "A arte da programação de computadores". A matemática é abordada apenas em cerca de um quarto do livro, mas o exercício é difícil para nós, não matemáticos. Mesmo essa matemática "elementar", nós a usamos tanto em nossa carreira? Algumas pessoas provavelmente me diriam que ler o livro TACOP é um desperdício de tempo e provavelmente deveria dedicar tempo a algo mais prático, mesmo que o livro seja sobre programação (um pouco mais acadêmico em comparação com o livro explica coisas semelhantes). Mas acho que o autor investiu muito tempo e esforço para produzi-lo. Ele pode até escrever o conjunto completo de 5 livros, enquanto nós - o público - só temos a missão de lê-lo. Por que não?

Adam Lear
fonte
1
"o desempenho entre C / C ++ e Java não será significativo". Se isso acontecer em breve, envie-me um PM para revisar minhas habilidades em Java. Parei de usar Java há alguns anos por esses motivos.
27411 sakisk
3
A maioria dos códigos C / C ++ não acessa o hardware. Isso facilita, mas isso geralmente é oculto pelos drivers de dispositivo. Atrevo-me a dizer que 95% + do código C ou C ++ nunca interage diretamente com o hardware.
Pemdas 25/03
1
Eu sugeriria uma mudança de título para idiomas de baixo nível. Existem várias coisas de baixo nível (como os threads funcionam .. como seu sistema operacional funciona ... e assim por diante) que ainda têm valor, mesmo que conhecer C ++ ou Assembly não.
ShaneC
2
@faif, Para aplicativos em execução de longa data, um aplicativo Java pode acompanhar o ritmo de um aplicativo C / C ++. Após o aquecimento do Java. Isso se deve à tecnologia hot-spot que recompila o código Java para o código nativo ao longo do tempo. No entanto, para aplicativos de execução curta, o tempo de inicialização do Java ainda é horrível. Em algum momento, principalmente para aplicativos de servidor, a comunicação é mais um gargalo do que o processamento real.
Berin Loritsch 25/03
1
O @BerinLoritsch Java é relativamente rápido, sim, mas a sobrecarga de memória, a sobrecarga da biblioteca de tempo de execução, o acesso ao hardware de baixo nível e a pré-configuração da VM antes da execução (a fim de atingir diferentes limites de heap, por exemplo) são terríveis, em comparação com apenas um programa de baixo nível, executando no sistema operacional. Não se trata apenas de executar instruções na mesma ordem de magnitude.

Respostas:

18

Pergunta interessante. Sou um programador de C ++ há muito tempo que agora trabalha em C # (com um pouco de C ++ não gerenciado para trabalhos críticos de desempenho), e historicamente tive que adicionar um pouco de código de montagem ocasionalmente, geralmente por motivos de desempenho.

Alguns pontos na preparação de uma resposta à pergunta:

  • Para sua comparação, sugiro que a principal distinção entre as linguagens mencionadas, C # e Java, do outro conjunto Assembly, C / C ++ seja que as primeiras usem um tempo de execução gerenciado para fornecer coleta de lixo. Existem outras diferenças (por exemplo, portabilidade binária, tamanho da estrutura e portabilidade), mas como você está comparando diferenças de desempenho, esse é um dos principais contribuintes.

  • Assembly, C e C ++ estão longe de ser igualmente "de baixo nível". Eu acho que você está certo em associar as linguagens Assembly e C aos desenvolvedores de hardware / firmware / driver, mas o C ++ é normalmente usado em um nível mais alto e ainda está em uso pesado - embora claramente C # / Java esteja dando certo de acordo com o TIOBE índice.

  • Na camada C ++, eu adicionaria Objective-C, pois é mais parecido com C ++ que C # / Java. Finalmente, notei que, com a adição do shared_ptr <> e outros recursos de gerenciamento automático de recursos, esses idiomas têm suporte para algo próximo à coleta de lixo.

OK - vamos à sua pergunta principal: os engenheiros de software realmente precisam saber mais coisas de baixo nível?

Minha resposta: Sim

Razões:

  • Mesmo ao usar C # / Java, você provavelmente encontrará entidades da estrutura que requerem gerenciamento explícito de recursos e / ou problemas de gráficos de memória "fixados" em qualquer aplicativo não trivial. Você precisa entender como esses sistemas funcionam para efetivamente evitar e depurar esses problemas.
  • As plataformas móveis têm recursos mais limitados e, embora exista suporte para versões limitadas de Java e .NET em alguns, o domínio atual do iOS e do Objective-C sugere uma renovação por muito tempo renovada.
  • Desempenho: sempre que você atinge um muro de desempenho, provavelmente precisará cair em um pedaço de código compilado nativamente para contornar isso.
  • Suporte legado: sempre que você precisar interoperar para obter acesso a um recurso ainda não exposto (ainda) no código gerenciado, será necessário fazer o mesmo.

Boa pergunta - mas não vejo idiomas não gerenciados desaparecendo no curto prazo.

Holtavolt
fonte
Obrigado pela sua resposta. Vou continuar estudando mais sobre a base do computador (como sistema operacional, rede, mais matemática ... também apenas o suficiente para entender o princípio básico e não me concentrar muito em melhorar apenas a programação). Espero que seja útil um dia.
Amumu 25/03
1
Também ter uma compreensão mais profunda do que está acontecendo no nível inferior ajudará a informar suas decisões.
dietbuddha
1
Para adicionar meu 0,02, saber como algo é feito quando você exige que isso aconteça geralmente é uma coisa boa. Pode ajudar a tornar suas demandas mais razoáveis ​​e eficientes (aplica-se à programação de alto nível e talvez a chefes;)).
ssube
43
  • Que alguém legitimamente não aprenda e não entenda a funcionalidade de nível inferior, e ainda seja um desenvolvedor muito produtivo e valioso, já é o caso.
  • Que ninguém precisará aprender ou entender a funcionalidade de nível inferior, que sempre seria uma perda de tempo, nunca será o caso.

Como em qualquer disciplina de engenharia, existem muitas etapas para o produto final, todas importantes, exigem conhecimento e são valiosas. Na engenharia de software, em particular, temos muitas camadas de abstração. Todos são necessários e ninguém pode ser especialista em todos eles.

Dito isto, precisamos de mais desenvolvedores de C # / Java / Ruby do que de desenvolvedores de Assemby / C. Para nós, desenvolvedores de "nível superior", entender mais sobre o que acontece "oculto" é útil e nos tornará melhores desenvolvedores. Mas o mesmo acontece com muitas outras coisas . Como desenvolvedor .NET, por exemplo, há muito que eu posso aprender que me tornará mais produtivo, que estudar nossa Linguagem Intermediária (muito menos C ++ / C / Assmebly), embora muito útil, muitas vezes precisa ficar em segundo plano.

Patrick Karcher
fonte
7

Hoje, você pode ganhar a vida como programador sem conhecer as coisas de baixo nível. Eu acho que isso faz de você um programador melhor para conhecê-lo.

Manter um alto nível de competência com o material de baixo nível, no entanto, está se tornando cada vez menos importante. Quero dizer, eu não faço nada em montagem há 20 anos e provavelmente precisaria de uma atualização séria antes de poder ser produtivo novamente, mas os conceitos gerais de como as coisas funcionam nesse nível ainda fazem parte da minha consciência e acho que útil de tempos em tempos, mesmo quando se trabalha em idiomas de nível superior.

JohnFx
fonte
3

Acho que não, os desenvolvedores de kernel sempre precisarão de coisas de baixo nível. Também não custa entender como tudo funciona, se você entender fundamentalmente o que o código que está escrevendo realmente está fazendo, aprenderá a escrever um código melhor. Eu acho que remover o material de baixo nível é uma ideia horrível, pois esse pensamento abstrato é útil às vezes, mas pode realmente ser um obstáculo se você quiser que o problema seja resolvido da melhor maneira. Por exemplo, entender que quando você concatena cadeias de caracteres, na verdade, você está criando novas cadeias de caracteres, é importante, mas se você não entendeu como as cadeias foram implementadas, basta concatenar e aguardar os 5 minutos que seu programa leva para ser executado. Este é um excelente artigo sobre coisas como esta: http://www.joelonsoftware.com/articles/fog0000000319.html

Jesus Ramos
fonte
3

Isso depende do que o engenheiro de software está realmente trabalhando. É possível ter uma carreira produtiva, feliz e lucrativa sem nunca tocar em nada de baixo nível agora, mas isso não é apenas trabalhos de programação. Para que haja sistemas operacionais e compiladores, é preciso haver engenheiros trabalhando em sistemas operacionais e compiladores, e eles precisam conhecer C, C ++ e a linguagem de montagem de suas máquinas.

O desempenho também pode importar. Meu laptop atual é aproximadamente um milhão de vezes mais poderoso que o meu primeiro computador em casa, e o software em execução ainda pode levar tempo. Ainda posso ficar atrasado nos videogames. Obviamente, os videogames parecem melhores, porque cada um dos mais de um milhão de pixels na tela pode receber uma de milhões de cores (em oposição a mil posições de caracteres em preto e branco, com alguns dos caracteres sendo usados ​​para gráficos ) Duvido que obteremos outro aumento de mil vezes na potência do computador em um futuro próximo e, se o fizermos, espero que seja usada por software cada vez mais complexo.

Embora a maior parte do software comercial continue sendo escrita no que for mais rápido a ser produzido e lançado, o que geralmente não é C, continuará havendo muito espaço para especialistas em C e C ++.

David Thornley
fonte
2

"Com o hardware continuando melhorando, o desempenho entre C / C ++ e Java não será significativo, e os grandes jogos poderão ser programados em linguagens como Java".

Não acredito que essa afirmação esteja correta tão cedo. Sempre há um acerto no código gerenciado devido às verificações feitas nos bastidores. Também não é uma questão de hardware melhor, pois o hardware melhora, assim como os aplicativos que devem rodar neles. Um sistema que é gravado em código nativo precisa ter uma interface para código gerenciado. Há um impacto no desempenho que acontece ao alternar entre os dois.

No entanto, apenas uma porcentagem geralmente pequena de aplicativos realmente precisa desse código otimizado. A maioria dos aplicativos de linha de negócios funciona bem com qualquer código gerenciado, .net, java etc. Isso não significa que os aplicativos que precisam dele farão a troca em breve. No entanto, o assembly escrito à mão é muito menos usado agora, com os compiladores C / C ++ otimizados sendo tão bons. Recentemente, houve um sistema operacional totalmente escrito em assembly, portanto alguns ainda o estão utilizando. Também é muito importante no campo da segurança.

Eu diria que, para ser um desenvolvedor muito bom, é preciso entender o que está acontecendo em um nível baixo. Ajuda na solução de alguns problemas difíceis, especialmente ao chamar o código nativo.

Adam Tuliper - MSFT
fonte
@ Adam Tuliper "um SO escrito inteiramente em montagem" Interessante. Você pode me dar o nome do sistema operacional? Você fez um bom argumento sobre a solução de problemas.
Amumu 25/03
@ Adam: Um "SO" somente para montagem provavelmente não tem muitos sinos e assobios (como GUI animada e um programa de pintura), mas pode ser capaz de executar apenas um ou dois processos no modo de usuário ...
Macke
@ Macke: Você está brincando? Mais sistemas operacionais multitarefa foram escritos em linguagem assembly do que em C. O sistema operacional do qual o NT (o kernel do Windows) foi clonado foi escrito principalmente na linguagem assembly Macro-32.
bit-twiddler
1
@ bit-twiddler: Você tem certeza? A maior parte da serra fontes que estavam em êxtase ...
TMN
@TMN: O BLISS foi usado apenas para itens de SO de nível superior. Todo o kernel do VMS foi escrito em Macro-32. Eu mantive uma lista do código de processamento no nível de bifurcação por anos, porque achei que era uma idéia muito legal. O processamento no nível de bifurcação era um mecanismo pelo qual um manipulador de interrupções poderia agendar a parte não crítica de tempo de seu código para ser executada em um nível de prioridade de interrupção mais baixo. O processamento no nível de bifurcação foi renomeado para Chamadas de Procedimento Adiado no kernel do NT.
bit-twiddler
2

Eu acho que conhecer algumas coisas de baixo nível é muito útil para depuração, como, por exemplo, na programação incorporada, a maior parte é feita com C, no entanto, quando a depuração de um conjunto de conhecimento para esse controlador Micro específico é extremamente útil.

user6791
fonte
Aceita. Faço programação incorporada há cerca de 30 anos e, embora não tenha mais a necessidade de escrever muito código de montagem (tudo está em C), geralmente passo por um programa instrução por instrução.
tcrosley
Caramba, eu costumo depurar códigos C e C ++ no modo CPU no Windows. O conhecimento da arquitetura e do conjunto de instruções para o processador, bem como a organização do compilador em uso em tempo de execução, é um conjunto poderoso de habilidades a ter na mochila. Consulte o seguinte pergunta programmers.stackexchange.com onde eu detalhe GCC gerado código: programmers.stackexchange.com/questions/59880/...
bit-twiddler
2

Quando os computadores foram inventados, poucas pessoas sabiam usá-los. Agora, quase todas as residências de um país rico têm 1 ou mais computadores que podem ser utilizados pela pessoa comum. Muitas pessoas comuns têm empregos trabalhando em computadores diariamente. A pessoa comum tem a capacidade de usar um computador, mas ainda precisamos de programadores.

Da mesma forma, o programador médio não precisa conhecer ou programar regularmente em linguagem assembly. Essa é uma condição tanto das habilidades comercializáveis ​​quanto uma saudação de quão longe chegamos no mundo da tecnologia. As empresas precisam de computadores para automatizar tarefas. Portanto, os programadores que podem programar em .NET / Java estão em grande demanda.

As tarefas que podem ser automatizadas serão automatizadas. Nem todas as tarefas podem ser automatizadas. Nem toda automação é perfeita. Então, a montagem é importante? Claro. É necessário ser um "programador". Claro que não.

P.Brian.Mackey
fonte
0

Hmmm, eu realmente gosto de aprender coisas de baixo nível.

Talvez não seja o símile mais preciso, mas para mim é como aprender as maquinações dentro de um carro. Talvez eu não saiba como todas as peças funcionam umas contra as outras, mas é divertido saber que há um motor, um eixo de manivela, cilindros, diferenciais, guindastes, freios, óleo, combustão, refrigeração e, em seguida, fricção, estresse, calor, forças, ciência - termodinâmica, física, mecânica de fluidos ...

Talvez não seja muito útil (não poderei consertar um carro sabendo tudo isso), certamente não é profissionalmente prático, mas divertido. A arte para a arte: o entorno para o entorno.

Dínamo
fonte
0

Eu acho que uma regra prática é: quanto mais rápido for, menor será o nível de obtenção.

Portanto, seu jogo de tiro em primeira pessoa intensivo em gráficos ou seu sistema algorítmico de negociação de FX ainda são de nível bastante baixo (C ++, etc) porque a velocidade é fundamental. Mas o aplicativo da web que exibe um relatório de vendas no prazo? Inferno, você poderia escrever isso no Sinclair BASIC, e ainda seria aceitável.

Adrian Parker
fonte
1
-1: Eu acho que uma regra prática é: quanto mais rápido for, menor será o nível. - Apenas curioso, quantos anos você tem? Algoritmos melhores, arquitetura e hardware melhores irão acelerar a maioria dos aplicativos de software modernos. Jogos de computador e sistemas incorporados são exceções a esta regra.
Jim G.
Muito velho! :-) Você menciona melhores algoritmos, melhor arquitetura da máquina, melhor hardware - mas, a meu ver, eles têm um impacto equivalente na velocidade de execução do processo. Aumente a velocidade do processador e, em seguida, cada processo (deve) ser executado mais rapidamente, independentemente do idioma em que foi desenvolvido. Use um algoritmo de classificação lento e seu aplicativo seja mais lento do que o necessário, independentemente do que você escreveu. linguagem de programação de alto nível ainda faz uma diferença relativa à velocidade de execução. Se milissegundos são importantes, diminua. Os sistemas de negociação algorítmica não são escritos em Java.
Adrian Parker
0

Nem todos os trabalhos de engenharia de software são iguais . As pessoas que trabalham em sistemas operacionais, compiladores, estruturas, drivers de dispositivos, sistemas embarcados e computação científica de alto desempenho precisam muito de saber 'coisas de baixo nível'. As pessoas que escrevem formulários Access CRUD, ou carrinhos de compras PHP para lojas Mom e Pop, talvez nem tanto. Que tipo de engenharia de software você deseja fazer e deseja fazer isso pelo resto da sua vida?

Minha opinião é que você precisa aprender pelo menos um nível de abstração abaixo daquele em que costuma trabalhar. Se você trabalha em C / C ++, deve escolher uma arquitetura e montagem de máquina. Se você trabalha em PHP, deve entender HTTP e um pouco de C / C ++ ou Perl. Se o Access é o seu pão com manteiga, é melhor conhecer algumas teorias sobre RDB e talvez um pouco sobre COM ou .Net. Em algum momento de sua carreira, você acabará parado por um problema em um nível mais baixo de abstração e precisará ser capaz de se comunicar pelo menos um pouco com alguém que seja especialista nessa área. Você pode 'sobreviver' sem essas coisas? Claro, mas planejar apenas 'sobreviver' em um mercado de trabalho competitivo é perigoso.

Charles E. Grant
fonte
-1

Eu mesmo trabalho extensivamente em C # .NET e sempre me afastei de C, C ++. Recentemente, começou a procurar emprego e ficou surpreso ao ver quantos empregos estão disponíveis e exigem experiência em C, C ++. Inicialmente, pensei que C, C ++ estavam ficando desatualizados, mas olhando para os trabalhos disponíveis, não parece que é esse o caso.

user676938
fonte
-1

Todos os idiomas gerenciados listados possuem intérpretes ou máquinas virtuais escritas em C / C ++. Sem essas duas, a maioria das linguagens gerenciadas ou interpretadas nem existiria. Eu diria que você subestima o valor deles.

Pemdas
fonte
-1

Eu realmente odeio a própria noção de um conhecimento "prático" . Tudo o que você aprende é igualmente prático. Não importa se você não estará operando em um nível de abstração próximo ao hardware, simplesmente conhecer os conceitos desse domínio é sempre benéfico para a construção de novos conhecimentos em outro nível de abstração. Quanto mais conceitos relacionados você souber, melhor.

Pelo que normalmente faço, o C # é uma linguagem de nível muito baixo e considero algo muito próximo a um hardware. Mas ainda acredito que mesmo meu conhecimento rudimentar e enferrujado da eletrônica digital, do design da CPU etc. é muito útil para tudo o que estou fazendo.

SK-logic
fonte
@ Amumu disse: Você fez um bom argumento. As pessoas geralmente associam conhecimento que ganha muito dinheiro é "conhecimento prático". No entanto, eles têm razão. No mínimo, esperamos e devemos contribuir com a sociedade se não ganharmos dinheiro com as coisas que aprendemos, especialmente as que não beneficiam nossa vida. Por exemplo, podemos querer aprender filosofia ou maneiras de ajudar nossa vida a ter mais significado. Mas se passarmos um tempo estudando matemática, elétrica, mas a meio caminho, não podemos fazer nada e desperdiçar seu tempo.
Adam Lear
@ Anna Lear, o problema é que não se pode dominar uma habilidade "prática", diretamente aplicável, sem uma cobertura muito ampla de "não prática". Simplesmente porque todo o conhecimento neste mundo está fortemente conectado. Nenhum conhecimento pode ser uma "perda de tempo", não importa quão longe esteja de qualquer prática possível.
SK-logic
1
-1: Tudo o que você aprende é igualmente prático. - Uau. Talvez eu deva memorizar as respostas para todos os meus cartões de perguntas sobre "Trivial Pursuit"! ;)
Jim G.
@ Jim G., sim, você deve, desde que tenha tempo livre suficiente e isso não prejudique o aprendizado de algo que o faria avançar mais do que isso. Memorizar coisas "inúteis" é, de fato, uma maneira muito robusta de melhorar sua memória.
SK-logic
-1

Não, a maioria não precisa. Embora a prática de técnicas de baixo nível ofereça ao desenvolvedor um conhecimento melhor do que poderia afetar o ciclo como um todo, hoje em dia o desenvolvedor pode usar esse tempo para estudar tecnologias mais recentes, o que, por sua vez, requer conhecimento de material de baixo nível a ser desenvolvido, mas não deve ser invocado. em.

doc_id
fonte
-1

Na minha opinião, quando você usa a palavra "Engenheiro", você quer dizer que foi o homem / mulher que projetou e construiu as coisas do zero. O verdadeiro problema de um engenheiro de software é resolver um problema, mas que problema? É uma grande questão.

Um desenvolvedor é diferente de um engenheiro de várias maneiras. Um "desenvolvedor" é uma pessoa que geralmente constrói coisas em plataformas já existentes. Ele desenvolve as plataformas existentes ou constrói novas heranças das mais antigas, certamente usando o componente do sistema pai.

Um desenvolvedor geralmente pensa da perspectiva de negócios, ele não é um cientista. :) O desenvolvedor está mais próximo do usuário do sistema, eles pensam do ponto de vista do usuário e, portanto, acabam resolvendo problemas do usuário usando a tecnologia.

Um engenheiro inteligente. Ele é um cientista, ele resolve um problema muito genuíno. A maioria dos problemas, que o próprio computador tem como um recurso. Nós nunca chegamos perto desse problema, ele é encapsulado. Os engenheiros são os que deixam seus estudos para trás depois de pesquisar muito sobre o sistema existente e criam algo novo para resolver o problema, se a solução exigir, se o sistema precisar de um novo idioma, eles inventarão um novo idioma porque o sistema existente não é capaz de resolvendo esse problema. Os engenheiros acabaram construindo um sistema no qual os desenvolvedores construíram seu sistema.

De fato, um engenheiro de software precisa aprender e ser versado com coisas de baixo nível ... :)

Enquanto desenvolvedor, depende completamente de seu interesse. :)

Mohammad Abdurraafay
fonte
1
-1: Umm ... Os cargos não têm sentido, cara.
Jim G.