>

>

>

(fonte: pexels.com)

Amiúde ouvimos, aprendemos e até usamos termos ou frases que não entendemos completamente. Eu acho isso bastante comum dentro da comunidade de desenvolvimento de software, seja RESTful Web APIs, metodologia Agile, Machine Learning, ou algum outro termo. Isto não é necessariamente uma coisa ruim, mas é importante entender quando você realmente sabe algo e quando você apenas sabe o nome para isso.

Para mim, Programação de Sistemas é um desses termos. Eu gostaria de tentar explicar, usando linguagem simples, o que isso significa.

Antes de podermos entender o que a Programação de Sistemas implica, precisamos primeiro entender o que é um Sistema. Software tende a cair em um de dois campos, software de sistema e software aplicativo.

System software é um software de computador projetado para fornecer uma plataforma para outros softwares. Exemplos de software de sistema incluem sistemas operacionais, software de ciência computacional, motores de jogos, automação industrial e software como aplicações de serviço.
… Tal software não é considerado software de sistema quando pode ser desinstalado normalmente sem afetar o funcionamento de outro software.
– wikipedia.org

System software é uma plataforma composta por programas e serviços de Sistema Operacional (SO), incluindo configurações e preferências, bibliotecas de arquivos e funções utilizadas para aplicações de sistema. O software de sistema também inclui drivers de dispositivos que executam hardware básico do computador e periféricos.
– techopedia.com

Software de sistema refere-se aos arquivos e programas que compõem o sistema operacional do seu computador. Os arquivos de sistema incluem bibliotecas de funções, serviços de sistema, drivers para impressoras e outro hardware, preferências de sistema e outros arquivos de configuração. Os programas que fazem parte do software de sistema incluem assemblers, compiladores, ferramentas de gerenciamento de arquivos, utilitários de sistema e depuradores.
– techterms.com

A definição da Wikipedia é muito vaga sobre o que é considerado software de sistema, desde que ele esteja fornecendo serviços para outras aplicações. No entanto as outras duas definições focam puramente no sistema operacional – drivers, kernels, bibliotecas e funções (pense em arquivos de cabeçalho kernel/libc e objetos compartilhados). Isto implica uma relação próxima com o hardware. Se olharmos para outro artigo da Wikipedia sobre Programação de Sistemas vemos:

A programação de sistemas requer um grande grau de consciência de hardware.

O artigo continua a implicar que uma parte central da programação de sistemas é a necessidade de as coisas serem muito rápidas. Isto faz sentido porque nós precisaríamos saber muito sobre o hardware. Também faz sentido que a velocidade (performance) seria uma parte central da programação de sistemas se for uma plataforma para outro software.

Se a parte mais central da sua aplicação (a “plataforma” do software do sistema) for lenta, então toda a aplicação é lenta. Para muitas aplicações, especialmente em escala, isto seria uma quebra de contrato.

System Software in a Nutshell

As citações acima e outros recursos me levaram aos seguintes critérios para definir software de sistema:

  • Provê uma plataforma para outro software a ser construída.
  • Interfaces directas ou próximas com hardware de computador de modo a ganhar o desempenho necessário e expor abstracções (como parte da plataforma).

O que é e o que não é software de sistema

Exemplos do que é software de sistema:

  • OS Kernels
  • Condutores
  • Hipervisores de metal nu (e.g. Hyper-V e VM Ware ESXi)
  • Compilers (que produzem binários nativos) e Debuggers

Exemplos do que não é software de sistema:

  • Aplicação de Chat GUI (Slack, Discord, etc)
  • Aplicação JavaScript baseada na Web
  • A API de Serviço Web

Você notará que enquanto as API de Serviço Web fornecem um serviço para outros softwares, elas não interagem (tipicamente) com o hardware a fim de expor abstrações sobre ele. No entanto, existem aplicações que ficam dentro de uma área cinza média. As que vêm à mente são aplicações de computação de alto desempenho e software incorporado.

Aplicações de computação de alto desempenho (HPC), tais como negociação em tempo real em bolsas de valores, não costumam expor uma plataforma, mas é comum que eles escrevam código que interage diretamente com o hardware. Um exemplo seria contornar a pilha de rede oferecida pelo kernel e implementar sua própria pilha de rede falando diretamente com a(s) placa(s) de rede. Desta forma podemos ver como o software HPC compartilha muitas semelhanças com o software de sistemas, interagindo diretamente com o hardware a fim de fornecer os ganhos de performance necessários.

Desenvolvimento de software embutido também compartilha muitas semelhanças com o software de sistemas nesse código que é escrito para interagir diretamente com o hardware. Entretanto, quaisquer abstrações fornecidas são tipicamente consumidas pelo mesmo software e não poderiam ser consideradas uma plataforma.

É importante notar as aplicações que compartilham semelhanças com a nossa definição de software de sistemas, uma vez que você provavelmente verá as aplicações/empregos descritos nestes termos (software de sistemas, engenheiros de sistemas, etc.).)

Programação de Sistemas (+ Linguagens)

(Photo by Roman Spiridonov on Unsplash)

Sistemas definidos, podemos agora definir Programação de Sistemas como o ato de construir Software de Sistemas usando Linguagens de Programação de Sistemas. Suficientemente simples, certo?

Bem há uma coisa que saltamos, as linguagens. As pessoas frequentemente falam sobre Linguagens de Programação de Sistemas de maneiras como “X é ótimo, é rápido, compilado, e uma linguagem de programação de sistemas”. Mas todos estão na mesma página do que é uma linguagem de programação de sistemas?

Dadas as nossas definições de Sistemas eu definiria o critério para que uma Linguagem de Programação de Sistemas fosse:

  • Compilada com binários nativos
  • Pode ser construída sem dependências de outros softwares (incluindo um kernel)
  • Características de desempenho similares a outras linguagens de programação de sistemas

Disclaimer: Esta é a minha definição. Como não há critérios definidos, eu estou derivando uma definição do que faz sentido para mim dado o contexto no qual eu defini software de sistema.

Compile to Native Binary

Se uma linguagem não pode compilar para um executável que é diretamente interpretável pelo CPU então ela, por definição, está rodando em uma plataforma (por exemplo, JVM, Ruby VM, Python VM, etc). Pode haver alguns argumentos a serem feitos aqui, mas por simplicidade penso que este é um critério adequado.

Sem dependências

O argumento é semelhante à compilação de um binário nativo. Se a linguagem sempre requer que algum outro software esteja presente para ser executado, então ele está sendo executado em uma plataforma. Um exemplo disto é Go e está incluída a biblioteca padrão. Ela requer suporte do sistema operacional para executar ações básicas como alocação de memória, desova de threads (para os goroutines rodarem), para o seu poller de rede embutido e outras ações. Embora seja possível reimplementar estas funções centrais, isto cria uma barreira para o uso neste contexto e é fácil de imaginar porque nem todas as linguagens, mesmo aquelas que compilam para binários estáticos, são destinadas como linguagens de programação do sistema.

Características de Desempenho Similares

Esta é um pouco de cop-out. No entanto, é para dizer que dentro do sistema de linguagens tipicamente classificadas como linguagens de programação de sistemas, não deve haver grandes diferenças (ordem de grandeza) nas características de desempenho. Por características estou me referindo explicitamente à velocidade de execução e eficiência da memória.

O padrão dourado para comparação é C e/ou C++ como é frequentemente representado em benchmarks comparativos, que medem a velocidade de execução em quantas ordens de grandezas as linguagens são mais lentas que C/C++.

Nomeando um Pouco

As linguagens que vêm à mente imediatamente, dada a definição acima são C e C++. Mas existem também novas linguagens como Rust e Nim, que também preenchem este nicho. De facto, já existe um SO escrito inteiramente em Rust (RedoxOS) e um kernel em Nim (nimkernel).

Let’s Talk About Go

Earlier Eu insinuei que Go pode não se enquadrar na família de “linguagens de programação de sistemas”. No entanto, assim como nem todas as aplicações se encaixam bem em software de aplicação e software de sistema, nem as linguagens.

Muitas pessoas chamarão Go de linguagem de programação de sistemas e até golang.org é citado como:

Go é uma linguagem de uso geral projetada com a programação de sistemas em mente.

No entanto, mesmo isto não é uma afirmação direta de que Go é uma linguagem de programação de sistemas, simplesmente que é projetada com isto em mente. Eu acho que ela está no meio.

While Go compila binários nativos, contém conceitos úteis de baixo nível (ponteiros em bruto/insegurança, tipos nativos como bytes e int32, e suporte a montagem em linha), e é relativamente performativa; ainda tem alguns desafios a superar. Go navios com um tempo de execução e um coletor de lixo.

Um tempo de execução significa que bootstrapping/overriding do tempo de execução será necessário para rodar em ambientes sem kernels. Isto entra mais na implementação interna da linguagem, o que pode mudar em lançamentos futuros. Mudanças requerem trabalho de bootstrapping adicional conforme a linguagem evolui.

A garbage collector (GC) significa que o Go é restrito em quais domínios de aplicação ele pode ser usado ou que o GC deve ser desabilitado e substituído por gerenciamento manual de memória. No caso do GC não poder ser substituído, o domínio em tempo real (definido por operações que devem ser completadas dentro de determinados limites de tempo e/ou o desempenho é medido em nano-segundos) não seria capaz de arriscar tempos de pausa não determinísticos de um GC.

Software de Sistemas Distribuídos

Com a crescente conversa sobre sistemas distribuídos, e aplicações como Kubernetes se tornando muito popular, podemos ouvir uma série de vocabulário novo que (se estivermos sendo honestos) a maioria de nós não entende completamente.

Até este ponto, eu vi os termos programação de sistemas e engenheiros de sistemas usados em contextos onde o que eles realmente significavam era programação de sistemas distribuídos e engenheiros de sistemas distribuídos.

Nós definimos software de sistemas, linguagens de sistemas, e programação de sistemas neste post. Entretanto, quando falamos de sistemas distribuídos, o significado de sistema muda. E embora eu não vá mergulhar nas diferenças específicas aqui (principalmente porque eu mesmo ainda preciso de as entender melhor), é importante que façamos essas distinções mentais e usemos um discurso mais exacto quando pudermos evitar confusão para aqueles que ainda estão a aprender o espaço.

Articles

Deixe uma resposta

O seu endereço de email não será publicado.