Se você é um programador, não se considere um "cientista da computação"; são os cientistas da computação que estão criando a próxima geração de computadores, alguns dos quais ainda são ficção científica até que a mistura correta de materiais, miniatuização e teoria computacional seja obtida. Eles são apenas o começo do pipeline. As pessoas que desenvolvem software aqui e agora são "engenheiros de software"; eles levam as teorias e ferramentas, às vezes colocando a teoria prática e as ferramentas do mundo real no topo, para aproveitar o poder em potentia dessa complexa peça de magia eletroínica e fazê-la fazer o que queremos. Essa é, por sua vez, uma especialização do campo da "engenharia da computação", que utiliza as teorias dos cientistas da computação e as aplica, hardware e software, a soluções eletrônicas do usuário final do mundo real.
É na IMO que os negócios encontram a teoria. Nesses tipos de casos, o velho ditado "o inimigo de melhor é bom o suficiente" pode ser facilmente mudado para ler "o inimigo de melhor é bom". Considerar-se um "engenheiro" em vez de um "cientista" e colocar o que você faz em paralelo com outras disciplinas de engenharia lança as diferenças em relevo.
Digamos que um cliente chegue até você, um engenheiro civil / estrutural, e peça para você construir uma ponte. A ponte precisa se estender por 20 pés, sustentar-se e transportar uma tonelada de carga, deve durar 10 anos com manutenção de rotina e eles a querem em um mês por US $ 20.000. Essas são suas restrições; atender aos mínimos, sem exceder os máximos. Fazer isso é "bom o suficiente" e recebe o salário. Seria uma engenharia ruim para você construir a Ponte Golden Gate, excedendo em muito as especificações de projeto e o orçamento em várias ordens de magnitude. Você geralmente acaba comendo os custos excedentes e pagando multas por excesso de tempo. Também seria uma má engenharia para você construir uma ponte de corda com o peso de cinco homens adultos, mesmo que custe apenas US $ 1000 em tempo e materiais; você não recebe boas críticas e depoimentos de clientes,
De volta ao software, digamos que você tenha um cliente que precisa de um sistema de processamento de arquivos criado para digerir os arquivos que entram e colocar as informações no sistema. Eles querem isso em uma semana e precisam lidar com cinco arquivos por dia, com cerca de 10 MB de dados, porque esse é todo o tráfego que eles recebem atualmente. Suas preciosas teorias vão amplamente pela janela; sua tarefa é criar um produto que atenda a essas especificações em uma semana, pois, ao fazer isso, você também atende ao orçamento de custos do cliente (como os materiais geralmente são uma gota no balde para um contrato de software desse tamanho). Passar duas semanas, mesmo com dez vezes o ganho, não é uma opção, mas o mais provável é que não seja um programa criado em um dia que possa lidar apenas com metade da taxa de transferência, com instruções para ter duas cópias em execução.
Se você acha que esse é um caso marginal, está errado; esse é o ambiente diário da maioria dos alojamentos internos. O motivo é o ROI; esse programa inicial não custa muito e, portanto, se paga muito rapidamente. Quando os usuários finais precisam fazer mais ou ir mais rápido, o código pode ser refatorado e redimensionado.
Essa é a principal razão por trás do estado atual da programação; a suposição, confirmada por toda a história da computação, é que um programa nunca é estático. Ele sempre precisará ser atualizado e, eventualmente, será substituído. Paralelamente, o aprimoramento constante dos computadores nos quais os programas são executados permite diminuir a atenção à eficiência teórica e aumentar a atenção à escalabilidade e paralelização (um algoritmo que é executado no tempo do quadrado N, mas que pode ser paralelo para rodar nos N núcleos). parecem lineares e, geralmente, o custo de mais hardware é mais barato que o dos desenvolvedores para criar uma solução mais eficiente).
Além disso, existe o princípio muito simples de que toda linha de código de desenvolvedor é outra coisa que pode dar errado. Quanto menos um desenvolvedor escreve, menos provável é que o que ele escreve tenha um problema. Isso não é uma crítica à "taxa de erros" de ninguém; é uma simples afirmação de fato. Você pode saber como escrever um MergeSort para frente e para trás em 5 idiomas, mas se você digitar apenas um identificador em uma linha de código, a Classificação inteira não funcionará, e se o compilador não o capturar, poderá levar você horas para depurá-lo. Compare isso com List.Sort (); está lá, é eficiente no caso geral e, aqui está a melhor coisa, já funciona.
Portanto, muitos dos recursos das plataformas modernas e princípios das metodologias de design modernas foram criados com isso em mente:
- OOP - construa dados e lógica relacionados em um objeto, e sempre que o conceito desse objeto for válido, ele será o objeto ou uma derivação mais especializada.
- Modelos pré-criados - um bom código de 60% ou mais é uma crença sintática e o básico para fazer o programa mostrar algo na tela. Ao padronizar e gerar automaticamente esse código, você reduz a carga de trabalho do desenvolvedor pela metade, permitindo um aumento na produtividade.
- Bibliotecas de algoritmos e estruturas de dados - Como descrito acima, você pode saber como escrever uma pilha, fila, QuickSort etc., mas por que precisa, quando há uma biblioteca de códigos com tudo isso incorporado? Você não reescreveria o IIS ou o Apache porque precisava de um site; então, por que implementar um algoritmo QuickSort ou um objeto em árvore vermelho-preto quando várias excelentes implementações estão disponíveis?
- Interfaces fluentes - Na mesma linha, você pode ter um algoritmo que filtra e classifica os registros. É rápido, mas provavelmente não é muito legível; o desenvolvedor júnior levaria um dia apenas para entendê-lo e muito menos fazer as alterações cirúrgicas necessárias para classificar em um campo adicional no objeto de registro. Em vez disso, bibliotecas como o Linq substituem muitos códigos muito feios e quebradiços por uma ou duas linhas de chamadas de método configuráveis para transformar uma lista de objetos em objetos projetados filtrados, classificados e projetados.