Compilador:

Compilador é um programa que traduz todas as suas linhas de código para outra linguagem – normalmente, uma de alto nível para outra de baixo nível (Assembly ou linguagem de máquina), ao ser compilado gera outro código que é interpretado pelo computador. Este código compilado é chamado de código objeto, podendo ser um arquivo executável que é reproduzido em um sistema operacional, por exemplo. Este tipo de tradutor é um dos mais utilizados. Delphi, Rust, C++ e Swift figuram na lista de compiladas.

-geração de código executável
 – depende da plataforma de execução
– tradução lenta X execução rápida


Vantagens:

·         O código compilado é mais rápido de ser acessado;
·         Impossibilita ou pelo menos dificulta ser quebrado e visualizado o código-fonte original;
·         Permite otimização do código por parte do compilador;
·         Compila o código somente se estiver sem algum erro.

Desvantagens:

·         Para ser utilizado o código precisa passar por muitos níveis de compilação;
·         Assim como vantagem a possibilidade de não poder visualizar o código-fonte, pode ser uma desvantagem;
·         Processo de correção ou alteração do código requer que ele seja novamente recompilado.

Interpretador:


Um interpretador também é um programa, mas, ao contrário do compilador, ele não converte o código todo para linguagem de máquina de uma vez. Ele executa diretamente cada instrução, passo a passo, , o programa vai sendo utilizado na medida em que vai sendo traduzido. Cada execução do programa precisa ser novamente traduzido e interpretado. MATLAB, Lisp, Perl e PHP são apontadas como interpretadas.
– sem geração de código 
– execução lenta, independente de plataforma

O interpretador analisa sintaticamente e semanticamente o código, se estas duas etapas forem realizadas e executadas de forma correta o código está pronto para funcionar.  

Vantagens:

·         Correções e alterações são mais rápidas de serem realizadas;
·         Código não precisa ser compilado para ser executado;
·         Consomem menos memória.

Desvantagens:

·         Execução é mais lenta do programa;
·         Necessita sempre ser lido o código original para ser executado;


Sistema computacional Hardware, software e dados computacionais que interagem para resolver problemas.
Hardware computacional Os elementos físicos de um sistema computacional.
Software computacional Os programas que fornecem as instruções que um computador executa.

                     Sistema computacional
É uma entidade dinâmica, usada para resolver problemas e interagir com seu ambiente. 
Ele é composto de hardware, software e pelos dados que eles gerenciam. 
                       Hardware computacional
É a coleção de elementos físicos que formam a máquina com suas respectivas partes.
                        Software computacional
É a coleção de programas que fornecem as instruções para um computador funcionar. 

Camadas de um Sistema Computacional
Composto de muitas camadas. Cada camada desempenha um papel específico no projeto geral do sistema.

informação, reflete o modo como representamos as informações em um computador,  gerenciada usando dígitos binários, 1 e 0.
hardware, consiste na parte física de um sistema computacional, inclui dispositivos como portas e circuitos que controlam o fluxo de eletricidade. CPU, Memória
A camada de programação lida com o software, as instruções usadas para realizar cálculos e gerenciar dados.
 sistema operacional (SO) para ajudar a gerenciar os recursos computacionais. Sistemas operacionais, tais como Windows XP, Linux ou Mac OS, nos ajudam a interagir com o sistema computacional e a gerenciar a forma pela qual dispositivos de hardware, programas e dados interagem entre si.

As camadas anteriores (mais internas) têm como foco fazer um sistema computacional funcionar. A camada de aplicativos, diferentemente, se concentra na utilização do computador para solução de problemas específicos do mundo real.
comunicação Computadores são ligados em redes para que possam compartilhar informações e recursos.

Abstração
Os níveis de um sistema computacional que acabamos de examinar são exemplos de abstração.
 É um modelo mental, uma maneira de pensar sobre alguma coisa que remove ou esconde detalhes complexos.
 Quando estamos lidando com um computador, em uma camada, não precisamos ficar pensando sobre os detalhes das outras camadas.

Uma Breve História da Computação


Babbage e o mecanismo analítico
Ada Augusta
Cartão Perfurado
IBM
inventou um modelo matemático abstrato chamado de máquina de Turing
ENIAC dispositivo que poderia rapidamente manipular números

Primeira Geração (1951-1959)
construídos usando válvulas para guardar informações.
gerava uma grande quantidade de calor e não era muito confiável, exigiam sistemas de refrigeração de grande carga e frequente manutenção.
a programação era realizada diretamente na linguagem de máquina
 O armazenamento dos dados era realizado em cartões perfurados, que depois passaram a ser feitos em fita magnética.
Ex: ENIAC
O dispositivo de memória primária da primeira geração de computadores era um cilindro magnético  que girava sob uma cabeça de leitura/escrita.
Nenhum dos computadores da primeira geração possuíam aplicação comercial, eram utilizados para fins balísticos, predição climática, cálculos de energia atômica e outros fins científicos.

Segunda Geração (1959-1965)
substituição da válvula pelo transistor, eram muito menores do que as válvulas, não exigiam tempo de pré-aquecimento, consumiam menos energia, geravam menos calor e eram mais rápidos e confiáveis. 
Na segunda geração o conceito de Unidade Central de Procedimento (CPU), memória, linguagem de programação e entrada e saída foram desenvolvidos. O tamanho dos computadores diminuiu consideravelmente. Outro desenvolvimento importante foi a mudança da linguagem de máquina para a linguagem assembly, também conhecida como linguagem simbólica. A linguagem assembly possibilita a utilização de mnemônicos para representar as instruções de máquina.
Em seguida vieram as linguagens de alto nível, como, por exemplo, Fortran e Cobol. No mesmo período surgiu o armazenamento em disco, complementando os sistemas de fita magnética e possibilitando ao usuário acesso rápido aos dados desejados.

A Terceira Geração (1965-1971)
marcada pela utilização dos circuitos integrados, também conhecidos como microchips. construídos integrando um grande número de transistores, o que possibilitou a construção de equipamentos menores e mais baratos.
começaram a surgir os computadores pessoais Computador Apple I.
IBM iniciando o mercado da indústria de softwares. Isto foi possível devido a utilização das linguagens de alto nível nestes computadores.

Quarta Geração (1971-?)
surgimento dos processadores — unidade central de processamento. Os sistemas operacionais como MS-DOS, UNIX, Apple’s Macintosh foram construídos. Linguagens de programação orientadas a objeto como C++ e Smalltalk foram desenvolvidas. Discos rígidos eram utilizados como memória secundária.
Os computadores eram mais confiáveis, mais rápidos, menores e com maior capacidade de armazenamento. Esta geração é marcada pela venda de computadores pessoais

Quinta Geração (1991 — dias atuais)


Os computadores da quinta geração usam processadores com milhões de transistores. Nesta geração surgiram as arquiteturas de 64 bits, os processadores que utilizam tecnologias RISC e CISC, discos rígidos com capacidade superior a 600GB, pen-drives com mais de 1GB de memória e utilização de disco ótico com mais de 50GB de armazenamento.
A quinta geração está sendo marcada pela inteligência artificial e por sua conectividade. A inteligência artificial pode ser verificada em jogos e robores ao conseguir desafiar a inteligência humana. A conectividade é cada vez mais um requisito das indústrias de computadores. Hoje em dia, queremos que nossos computadores se conectem ao celular, a televisão e a muitos outros dispositivos como geladeira e câmeras de segurança.

Algoritmo?
Usamos algoritmos no dia-a-dia geralmente sem perceber, por exemplo em uma receita de bolo, é preciso seguir as instruções para chegar a uma conclusão.
Para que o computador consiga entender, ele precisa de uma linguagem específica, estas linguagens utilizam uma lógica para serem escritas e é aí que entram os algoritmos.
Definição: algoritmo é uma sequência lógica, finita, não ambígua e definida de instruções que devem ser seguidas para resolver um problema ou executar uma tarefa.
Uma linguagem de programação serve como meio de comunicação entre o indivíduo que deseja resolver um determinado problema e o computador.
Característica de uma Linguagem de Programação
Legibilidade: facilidade de ler e escrever programas, Simplicidade: que cada conceito seja simples de aprender e dominar, Expressividade: representação clara e simples de dados e procedimentos a serem executados pelo programa, Ortogonalidade: construções primitivas podem ser combinadas para construir as estruturas de controle de dados, Portabilidade: -multiplataforma: capacidade de um software rodar em diferentes plataformas sem a necessidade de maiores adaptações; -longevidade: possibilidade de usar o mesmo software após ema mudança de hardware. , Confiabilidade: software de acordo com as especificações
● E m resumo
– Legibilidade e facilidade de escrita melhoram
confiabilidade.
– A dificuldade em escrever ou entender o algoritmo
resulta em potenciais erros de programação
Simplicidade X Ortogonalidade
ortogonalidade é fortemente relacionada à simplicidade: quanto mais ortogonal o projeto de uma linguagem, menor é o número necessário de exceções às regras da linguagem. Menos exceções significam um maior grau de regularidade no projeto, o que torna a linguagem mais fácil de aprender, ler e entender.

Histórico ● Inicialmente, a programação de computadores se resumia a Assembly ou algo similar ● Na década de 50, diversas linguagens surgiram, as quais são as ancestrais das linguagens que usamos hoje em dia ● Fortran ● COBOL ● LISP ● Algol 60 Histórico Histórico ● Na década de 80 os projetistas de linguagens passaram a considerar requisitos de mais alto nível, como desempenho, programação em larga escala e estruturas mais inteligentes ● C++ ● Ada ● Eiffel ● Perl Histórico ● Na década de 90 entramos na era da internet, onde as linguagens passam a se importar com conexão à rede, integração com navegadores, etc (preocupações da década anterior ainda persistem) ● Python ● Java ● Haskell ● Ruby ● PHP ● C#



Paradigma? Paradigma é um modelo ou padrão de raciocínio a seguir, seria a maneira como um determinado programador resolve um certo problema, como o programador estrutura e executa este programa.
Os quatro principais paradigmas de programação são: paradigma imperativo, declarativo, funcional e orientado a objetos.

Paradigma Imperativo
“Primeiro faça isso e depois faça aquilo.”
Imperatividade dá a ideia de dar ordens
Baseado em instruções e comandos, o programador diz como e o quê exatamente um programa ou rotina deve realizar. 
Instruções como ifwhileswitch for são típicas de linguagens de programação imperativas.
O fundamento da programação imperativa é o conceito de Máquina de Turing dispositivo teórico (imaginário) conhecido como máquina universal, invenção automática capaz de manipular símbolos em uma fita de acordo com uma série de regras para guardar informação.que nada mais é que uma abstração matemática que corresponde ao conjunto de funções computáveis.
Na Segunda Guerra Mundial, a máquina ENIAC foi desenvolvida, custos de manutenção e implementação eram muito altos. John von Neumman reconheceu que um programa e suas variáveis podem residir na memória principal de um computador. O paradigma imperarivo é criado para da suporte a essa nova arquitetura. Os comandos são executados na ordem que aparecem na memória. C ADA JAVA
Atribuições, Declarações e Expressões
Atribuição: Alterar o valor de um local da memória e destruir o valor anterior.
Declaração de variável: NOME a um local de memória e TIPO a valores armazenados.
Interpretar Expressões

Recuperar valores em um determinado endereço de memória.
linguagens puramente imperativas, como Assembly

Alguns exemplos de linguagens de programação que baseiam-se no modelo imperativo:
Ex: ADA, BASIC, Fortran;Pascal;  Python;  Lua; COBOL, FORTRAN, C, PASCAL …
Máquina de Turingdispositivo teórico (imaginário) conhecido como máquina universal, invenção automática capaz de manipular símbolos em uma fita de acordo com uma série de regras para guardar informação.

https://medium.com/@phinfonet/programa%C3%A7%C3%A3o-funcional-o-que-diabos-%C3%A9-isso-da9f230b9be2

Paradigma funcional
“Subdividir o problema em outras funções e resolver cada uma separadamente, pois os resultados encontrados serão utilizados posteriormente.”
Cada bloco recebe no topo uma entrada de dados e retorna, na base, os dados de saída. A solução geral é dividida em várias funções (daí o nome funcional) que, no final, se associam para mostrar o resultado na tela. As variáveis não variam.

Ex: APL, LISP, HASKELL, F#, ErlangElixirMathematica.

Paradigma lógico

“Oferecer um arcabouço(estrutura) que permita inferir conclusões desejadas, a partir de premissas, representando o conhecimento disponível, de uma forma que seja computacionalmente viável”. 
Faz uso da lógica matemática, a abordagem do paradigma lógico é expressar programas na forma de lógica simbólica(faz uso de símbolos) e usar um processo de inferência lógica (executar uma dedução ou demonstração) para produzir resultados
 Exemplo: Prolog, Mercury;  Oz;  Frill, 

Paradigma Orientado a Objetos
“Um sistema construído usando um método orientado a objetos é aquele cujos componentes são partes encapsuladas de dados e funções, que podem herdar atributos e comportamento de outros componentes da mesma natureza, e cujos componentes comunicam-se entre si por meio de mensagens”.  
Utilizamos uma lógica bem próxima do mundo real, lidando com objetos, Nele, implementa-se um conjunto de classes que definem objetos e nessas classes os comportamentos são chamados de métodos e os estados possíveis da classe são chamados de atributos.
Ex: C#JavaPHPRubyC++Python

Crise do Software de 1970
O termo Crise do Software surgiu para descrever as dificuldades enfrentadas no desenvolvimento de software no fim da década de 60, expressava as dificuldades do desenvolvimento de software frente ao rápido crescimento da demanda por software e da complexidade dos problemas a serem resolvidos, uma vez que a engenharia de software era inexistente,  

O termo expressava as dificuldades enfrentadas no desenvolvimento de software devido ao rápido crescimento da demanda por softwares a complexidade dos problemas a serem resolvidos e a inexistência de técnicas de desenvolvimento, uma vez que a engenharia de software era inexistente.
Com tudo a maior consequência da crise foi o surgimento da engenharia de software o qual visa no desenvolvimento de tecnologias que facilitem e permitam a obtenção de softwares eficientes e baratos, sua importância o fez tornar-se um novo campo de pesquisa na computação.

começaram a falhar
constantemente nos prazos de entrega, apresentando resultados insatisfatórios e além dos orçamentos que ultrapassavam o predeterminado.

As causas da crise do software estão ligadas a complexidade do processo de software e a relativa imaturidade da engenharia de software como profissão. A crise se manifesta de várias formas:
  • Projetos estourando o orçamento;
  • Projetos estourando o prazo;
  • Software de baixa qualidade;
  • Software muitas vezes não satisfaz os requisitos;
  • Projetos ingerenciáveis e código difícil de manter.
A maior parte dos projetos continuam com estes problemas ainda na atualidade, assim pode se dizer que a crise continua vigente ainda na atualidade.[1]
As soluções para a crise de software:


Engenharia de software é uma área da computação voltada à especificação, desenvolvimento e manutenção de sistemas de software, com aplicação de tecnologias e práticas de gerência de projetos e outras disciplinas, visando organização, produtividade e qualidade. estes profissionais projetam e guiam o desenvolvimento de programas, aplicativos e sistemas, de forma que atendam aos requisitos e cumpram as funções determinadas.
Engenharia de software é uma área da computação voltada à especificação, desenvolvimento, manutenção e criação de software
http://protocoloti.blogspot.com/2012/04/paradigmas-de-programacao.html https://pt.slideshare.net/gustavolgcr/paradigmas-de-programao-imperativo-orientado-a-objetos-e-funcional
https://www.profissionaisti.com.br/2010/10/paradigmas-de-programacao/
https://www.infoescola.com/informatica/historia-da-programacao/
https://universidadedatecnologia.com.br/linguagem-de-programacao-criterios/
http://www.linhadecodigo.com.br/artigo/489/linguagem-de-programacao.aspx

FINAL
Não Herdada // Não Sobrescrito

A classe não pode ser herdada ou estendida por outra classe, e nenhum de seus métodos poderão ser sobrescritos.
Obs: a palavra-chave final pode ser combinada com qualquer modificador de acesso, ou seja, uma classe pode ter acesso default ou público e ser também marcada como final.


package bebida;
public final class Refrigerante{  
//pública e final          
}

package bebida.brasil;
import bebida.Refrigerante;
/* erro de compilação - a classe Coca não pode herdar
 * de Refrigerante pq esta está marcada como final */
public class Coca extends Refrigerante { 
}


Classe final: impede que a classe seja herdada.
Método final: impede um método de ser sobrescrito em uma subclasse.

Argumento final: valor não poderá ser modificado dentro do método.

Nesse caso, “modificado” significa a retribuição de um novo valor à variável, ou seja, o argumento final deve manter o mesmo valor que o parâmetro tinha quando foi passado para o método até o final.

public class Argumentos {
      public void setArg(String obj1,
                         final String obj2) {
            String obj3 = new String();
            obj1 = obj3;
            /* erro, argumentos final não podem ter
             * um novo valor reatribuído */
            obj2 = new String();
            /* erro, argumentos final não podem ser
             * modificados */
            obj2 = obj3;          
      } 
}



Os modificadores de acesso definem o escopo de visibilidade da classe, ou seja, servem para restringir ou permitir o acesso a uma classe. 
Acesso= Visiabilidade



Acesso padrão ou default: Não possui modificador.
Esse é o chamado acesso em nível de pacote, pois classes com esse tipo de acesso só podem ser vistas (acessadas) por classes de dentro do mesmo pacote em que estão declaradas.
Por exemplo, criando duas classes com acesso padrão e as colocarmos em pacotes diferentes, uma não poderá enxergar a outra; ou seja, uma classe não poderá herdar ou criar instâncias da outra classe, ou até mesmo declarar um retorno ou uma variável com o tipo da outra classe.

Acesso public: Acesso público, permitindo que todas as classes de todos os pacotes a vejam e acessem.

Por exemplo, se duas classes possuem acesso público, uma poderá criar instâncias, herdar, declarar uma variável ou um retorno com o tipo da outra classe.

Exemplo de acessos default e público:


package bebida;
public class Bebida_alcoolica {  // acesso público
/* erro de compilação Bebida_alcoolica não tem acesso a classe Caipirinha porque estão em pacotes diferentes e Caipirinha possui acesso default */
Caipirinha c = new Caipirinha();
}

package bebida.brasil;
import bebida.Bebida_alcoolica;
class Caipirinha {  // acesso default
/* possui acesso a classe Bebida_alcoolica, mesmo em pacotes diferentes, porque Bebida_alcoolica possui acesso público */
Bebida_alcoolica b = new Bebida_alcoolica();
}


Classe Private: Métodos e variáveis marcadas como private só podem ser acessados pela classe na qual foram declarados;  outras classes não acessam membros privados nem por herança, nem por instância.

Membros protected: Pode ser acessado por classes do mesmo pacote por meio da instanciação, e acessado por classes de outros pacotes através de herança.
Obs: membros padrão e protected diferem apenas quando se trata de subclasses.

Enfim, protected acessa mesma classe, mesmo pacote por subclasse e não subclasse e pacote diferente pela subclasse.