Baixe o app para aproveitar ainda mais
Prévia do material em texto
Lista de exercícios Cap 1 - PLP - Robert W. SebestaLista de exercícios Cap 1 - PLP - Robert W. Sebesta 1. Por que é útil para um programador ter alguma experiência no projeto de linguagens, mesmo que ele nunca projete uma linguagem de programação? R:R: Alguns dos critérios para aprender paradigmas de linguagens de programação: • Capacidade aumentada para expressar ideias: As linguagens de programação usadas podem impor restrições no que diz respeito a abstração de idéias, estruturas de controle e de dados, logo o conhecimento mais amplo em linguagens faz com o programador não apresente tanta dificuldade na elaboração das idéias de construção do software. • Embasamento para escolher linguagens adequadas: linguagens são como ferramentas, logo devem ser escolhidas de acordo com a necessidade do projeto vigente. • Habilidade aumentada para aprender novas linguagens: Quando se aprende os conceitos dos paradigmas por traz de uma linguagem, fica muito mais fácil entender linguagens que utilizem aquele paradigma. • Melhor entendimento da importância da implementação: os conceitos de linguagens deprogramação podem levar a uma pessoa a ter um maior domínio de uma determinada linguagem de programação e por sua vez da implementação dela e de como usar seus recursos da melhor maneira possível. • Melhor uso de linguagens já conhecidas e consolidadas: os conceitos de linguagens de programação podem levar a uma pessoa a saber mais sobre uma linguagem que ela já utilize. • Avanço geral da computação: Uma determinada linguagem pode acabar sendo melhor que outra, mas não apresentar muita notoriedade. Em alguns casos uma determinada linguagem pode ser baseada em uma mais antiga, trazendo consigo aspectos antigos e novos. 2. Como o conhecimento de linguagens de programação pode beneficiar toda a comunidade da computação? R:R: Uma linguagem de programação poderá X poderá ganhar notoriedade em face uma linguagem de programação Y com base em possíveis “falhas” da X. Ou seja, a comunidade poderá ganhar novas linguagens que substituem aquelas que são tidas como “ruins” ou até mesmo criar novas para atingir objetivos específicos (suponha que Y é uma linguagem boa, mas não possui recursos web, uma nova linguagem W poderá ser construída com base em Y e mais outros elementos para preencher a lacuna de linguagem para web). Em suma, a comunidade pode sempre verificar os pontos fortes e fracos numa linguagem, criando outras melhores, tomando como base sempre os pontos fortes dela (e seu paradigma) e melhorando o que falta. 3. Que linguagem de programação tem dominado a computação científica nos últimos 50 anos? R:R: Fortran tem sido muito utilizada no ramo da computação científica, tendo sofrido diversas atualizações durante os anos. 4. Que linguagem de programação tem dominado as aplicações de negócios nos últimos 50 anos? R: R: COBOL, uma vez que é considerado com uma excelente linguagem geradora de relatórios. 5. Que linguagem de programação tem dominado a Inteligência Artificial nos últimos 50 anos? R:R: Lisp, uma vez que a linguagem utiliza a notação lambda e também trabalha extensivamente com listas e outras estruturas elementares tanto utilizadas em aplicações de inteligência. 6. Em que linguagem o UNIX é escrito? R:R: O sistema Unix foi escrito em linguagem C, em meados de 1970. Denis Ritchie foi o idealizador desta linguagem e graças ao sistema Unix ela obteve uma grande fama. Atualmente C é muito utilizado em sistemas embarcados. 7. Qual é a desvantagem de ter muitas características em uma linguagem? R: R: Uma linguagem que contenha muitos recursos tenderá a consumir muito processamento ou espaço em memória. 8. Como a sobrecarga de operador definida pelo usuário pode prejudicar a legibilidade de um programa? R:R: Uma sobrecarga de operadores consistente e bem definida poderá deixar o código relativamente simples de ser escrito e entendido, mas se for feita de qualquer maneira poderá ter consequências desagradáveis. Vamos supor o caso do operador de adição “+”. Se ele for permitido para a soma de valores inteiros e flutuantes, isso gerará uma facilidade de compreensão e escrita no código, trazendo até certa simplicidade. No entanto se algum usuário tiver a possibilidade de usá - lo para quaisquer outras operações, poderá acarretar no não entendimento do código por parte de outro desenvolvedor, deixando - o confuso. Se pegarmos por exemplo o operador “++”, utilizado pelo C/C++ como operador de incremento de uma unidade (principalmente me laços for) e sobrecarregarmos ele para qualquer outra coisa, um outro programador C ou C++ poderá não entender o código ao vê - lo sendo usado de uma forma não convencional. 9. Cite um exemplo da falta de ortogonalidade no projeto da linguagem C. R: R: C apresenta basicamente dois tipos de dados estruturados: vetores e registros (structs). Os registros podem ser retornados por funções, no entanto, vetores não podem. C utiliza void para indicar a “não existência” de um elemento (ex: uma função tida como void não retorna nenhum valor). Neste contexto, uma estrutura pode conter quaisquer tipos de dados, exceto o void ou uma estrutura de mesmo tipo. O mesmo ocorre com vetores: eles podem te quaisquer tipos, menos o tipo void. Ao utilizar passagem de valores para dentro de uma função ou procedimento, C utiliza a técnica de passagem por valor (ou seja, ele passa uma cópia dos dados para a função), no entanto, ao passar um vetor, o mesmo é passado como referencia. 10. Qual linguagem usou a ortogonalidade como um critério de projeto primário? R: R: Assembly utilizado pelas mainframes da IBM, principalmente se comparado com os minicomputadores VAX. 11. Que sentença de controle primitiva é usada para construir sentenças de controle mais complicadas em linguagens que não as têm? R: R: Você pode usar vetores e ponteiros para construir sentenças muito mais complexas, como por exemplo listas encadeadas, árvores e outros. No caso você poderá utilizar a ideia de vetores e ponteiros associados a algum tipo de dado primitivo, como o int, criando assim uma estrutura de dados como uma lista que armazena valores inteiros. 12. Que construção de uma linguagem de programação fornece abstração de processos? R: R: A abstração é algo tido como importante pois permite a facilidade de escrita de uma linguagem. Um exemplo de abstração pode ser encontrado na construção de uma função (subprograma), a fim de resolver algum problema específico nele. Se não fosse possível ter essa abstração, o código dessa função teria que ser replicado nos diversos pontos do programa onde ele fosse utilizado. 13. O que significa para um programa ser confiável? R: R: Um programa é tido como confiável quando está de acordo com suas especificações em todas as condições. Além disso existem basicamente dois pontos que levam um programa ser tido comoconfiável: • Verificação de tipos: Um programa executa testes para detectar erros de tipo, tanto em tempo de compilação, quanto em tempo de execução. • Tratamento de exceções: Um programa tem a habilidade de identificar e tratar erros, tomando medidas corretivas quando uma falha é encontrada ou uma exceção ocorre. 14. Por que verificar os tipos dos parâmetros de um subprograma é importante? R: R: quando a linguagem ou o ambiente em si é incapaz de realizar uma verificação de tipos de parâmetros passados a uma função, simplesmente deixando passar qualquer tipo, você poderá ter resultados inconsistentes. Por exemplo, se uma função tem em seu cabeçalho (definição da função) um parâmetro do tipo int e é passado a ela um tipo float, poderão haver problemas com relação aos cálculos feitos para se manter a representação de tal valor. Por exemplo, um int não possui representação da parte fracionária, o range de um int tende a ser muito menor que o de um float, o que gera um calculo de parte decimal muito defasado e sem nexo. Por fim,se o ambiente ou o compilador não é capaz de emitir nem um warning informando tal problema, a depuração torna - se praticamente impossível. 15. O que são apelidos? R: R: Apelidos são espécies de identificadores, geralmente utilizados quando se é possível ter um ou manis nomes definidos para acessar a mesma célula de memória. Um apelido por exemplo, pode ser definido quando dois ponteiros estão apontando para a mesma variassem. 16. O que é o tratamento de exceções? R R : O tratamento de exceções é a habilidade de um programa de interceptar erros em tempo de execução e contorna - los. 17. Por que a legibilidade é importante para a facilidade de escrita? R: R: A legibilidade é um dos conceitos mais importantes na hora de se avaliar uma linguagem de programação, pois ela compreende justamente a facilidade com que um programa pode ser entendido. Durante muito tempo, principalmente antes da década de 70, as linguagens de programação estavam mais próximas de “instruções de máquina” que do usuário em si, o que tornava a tarefa de construção de softwares algo muito mais complexo de ser feito e principalmente aprendido. Após os anos 70 e principalmente após do surgimento da idéias de ciclo de vida do software, as linguagens começaram a ter um nível de abstração maior, tornando - se mais fáceis de serem escritas, lidas e entendidas. Se uma linguagem é fácil de ser lida e entendida, supostamente isso implica que ela é tem um alto nível de abstração, além de ser fácil de ser escrita. 18. Como o custo de compiladores para uma linguagem está relacionado ao projeto dela? R:R: Dependendo de como é o projeto da linguagem, o compilador poderá ter que um grande número de checagens ou não antes de terminar o processo de compilação. Se a quantidade de checagens for muita, então ele poderá acabar tornando-se ineficiente. 19. Qual tem sido a influência mais forte no projeto de linguagens de programação nos últimos 50 anos? R:R: Arquitetura de computadores, principalmente no que diz respeito a arquitetura de Von Neumann. 20. Qual é o nome da categoria de linguagens de programação cuja estrutura é ditada pela arquitetura de computadores de von Neumann? R:R: São as linguagens classificadas como Imperativas. Linguagens desse tipo descrevem o programa em termos de seus estados, definindo ações que modifiquem tal estado. 21. Que duas deficiências das linguagens de programação foram descobertas como um resultado da pesquisa em desenvolvimento de software dos anos 1970? R:R: Primeiramente, antes dos anos 1970, as estruturas condicionais usavam muito “goto”, o que em muitos casos gerava problemas de legibilidade no código. Um outro problema foi a verificação de tipos primitivos. 22. Quais são os três recursos fundamentais de uma linguagem orientada a objetos? R:R: Encapsulamento, herança e polimorfismo. 23. Qual foi a primeira linguagem a oferecer suporte aos três recursos fundamentais da programação orientada a objetos? R:R: Smaltalk 24. Dê um exemplo de dois critérios de projeto de linguagens que estão em conflito direto um com o outro. R:R: Legibilidade e facilidade de escrita. 25. Quais são os três métodos gerais de implementar uma linguagem de programação? R:R: compilação, interpretação pura e sistemas híbridos. 26. Qual produz uma execução de programas mais rápida, um compilador ou um interpretador puro? R: R: Geralmente os programas compilados tendem a consumir menos tempo de execução. Ointerpretador puro terá que, em tempo de execução, ler as instruções, verifica - las e convertê-las a algo que maquina entenda. Já os sistemas híbridos possuem a facilidade de carregar somente módulos que são necessários naquele instante (just in time), o que pode reduzir consideravelmente o seu custo em relação ao tempo de execução. 27. Que papel a tabela de símbolos tem em um compilador? R:R: A tabela de símbolos serve como uma base de dados para o processo de compilação. O conteúdo primário na tabela de símbolos são informações de tipo e atributos de cada um dos nomes definidos pelo usuário no programa. Essa informação é colocada na tabela pelos analisadores léxico e sintático e é usada pelo analisador semântico e pelo gerador de código. 28. O que faz um ligador? R: R: O ligador (ou linker) é um programa de sistema que tem por objetivo coletar programas de sistemas e ligá - los aos programas de usuário, criando assim o módulo de carga (também conhecido como imagem executável). 29. Por que o gargalo de von Neumann é importante? R:R: A “máxima” por trás da arquitetura de Von Neumann é que “a velocidade de conexão entre a memória e o processador é o que define a velocidade do computador, isso porque as instruções podem ser executadas com mais freqüência do que movidas da memória para o processador.” Essa característica é conhecida como “Gargalo de Von Neumann” e é o fator responsável pelas pesquisas em computação paralela. A computação paralela por sua vez é uma forma de computação onde os vários cálculos que o processador realiza são quebrados em problemas menores (cálculos menores) e divididos para serem realizados ao mesmo tempo (ou seja, de forma paralela). 30. Quais são as vantagens de implementar uma linguagem com um interpretador puro? R:R: No modo de interpretação puro, o interpretador executa o código escrito de forma direta, sem a necessidade de um processo de compilação ou criação de um sistema intermediário (como o bytecode do Java). A medida que o programa vai sendo lido, ele vai sendo executado. Quando uma execução termina e o programa é chamado novamente, um novo processo de interpretação é realizado. As vantagens desse modelo consistem em: • Correções e alterações podem ser realizadas de forma muito mais rápida • Não há dispêndio do tempo de compilação. • Tende a consumir menos memória Conjunto de ProblemasConjunto de Problemas 1.Você acredita que nossa capacidade de abstração é influenciada por nosso domínio de linguagens? Defenda sua opinião. R:R: Em tese, sim. Acredito que a capacidade do programador de conseguir observar um problema e abstraí-lo de tal maneira que ele possa enxergar seus módulos, funções, objetos e outros elementos é algo que está a parte de qualquer linguagem de programação estando pautada puramente na lógica do programador. No entanto, ao codificar a solução, tal poderá ser diretamente atingida pela linguagem e por seu paradigma, influenciando em muito o resultado. Por exemplo: suponha que um programador queira criar um jogo e para isso opta por usar C. Pelo fato de C não dar suporte ao paradigma de OO (Orientação a Objetos), tal programador acabará tendo que passar por certos “problemas” que em linguagens de programação com suporte a OO ele não teria. 2.Que argumentos você pode dar a favor da ideia de uma única linguagem para todos os domínios de programação? R: R: A única vantagem nessa abordagem está na facilidade de conseguir “fazer tudo” utilizando uma única linguagem de programação. O programador deverá aprender somente esta linguagem, sua plataforma e ambiente de programação. 3.Java usa um símbolo de fechamento de chaves para marcar o término de todas as sentenças compostas. Quais são os argumentos a favor e contra essa decisão de projeto? R: R: No projeto foi determinado que o símbolo “{“ definiria a abertura de um bloco, enquanto que o “}” definiria o fechamento de bloco. Em tese isso tende a deixar a linguagem mais “arrumada”, pois permite que quem lê o código saiba quais instruções estão associadas entre si e seus respectivos escopos. No entanto, por justamente permitir que seja utilizado “{ }”, um programador poderá simplesmente ignorar a indentação do código, deixando - o mais confuso de ser lido e entendido, afetando em legibilidade. 4. Muitas linguagens distinguem entre letras minúsculas e maiúsculas em nomes definidos pelo usuário. Quais são as vantagens edesvantagens dessa decisão de projeto? R: R: O uso de caixa baixa e alta na definição dos identificadores pode ser usada para deixar o código mais fácil e legível, principalmente quando se utiliza nomes compostos, além de identificar se algo faz parte de alguma classe, interface ou biblioteca. Por exemplo, vamos supor os seguintes identificadores: “UIView” e “SKSpriteNode”. O “UI” do “UIView" serve para identificar que ele faz parte do pacote “UIKit”, responsável por interfaces de usuário; já o “SK" significa que ele faz parte do “SpriteKit”, biblioteca responsável por gerenciar os elementos básicos relacionados a jogos, como sprites, sons, e animações. Um outro uso de caixa alta seria relacionado ao nome de classes e objetos, como por exemplo, cachorro = new Cachorro(). Em suma, linguagens que permitem case sensitive, fazem isso visando ampliar a quantidade de identificadores que podem ser usados, padronizar o código e facilitar a leitura. Um ponto negativo fica com relação as linguagens que não requerem definição de tipo na declaração da variável, como por exemplo o Python, onde “varInteiro = 10” é diferente de “varinteiro = 10”, 5. Explique os diferentes aspectos do custo de uma linguagem de programação. R: R: Existem vários pontos a serem levantados na hora de avaliar o custo de uma linguagem de programação, a saber: • Treinamento de pessoal: Uma linguagem de programação requer de treinamento para a sua utilização. • Escrita de programas: Isso está relacionado a facilidade de escrita da linguagem, a qual depende da proximidade com o propósito da aplicação em particular. Ao criar uma linguagem de alto nível, seus esforços estão direcionados a criação de software de maneira menoscustosa. • Custo de compilação de programas. • Custo de execução: Dependendo do propósito e de como uma linguagem foi arquitetada, a mesma poderá realizar verificações durante o seu tempo de execução, o que elevará o seu tempo de execução, mas em contra partida poderá impedir falhas. • Implementação da linguagem e disponibilidade de compiladores: Uma linguagem chegará mais rápido ao público (e poderá ter uma fácil aceitação) se você ao terminar a de concebe-la, liberar o compilador dela de forma gratuita, fazendo assim com que várias pessoas possam testar tal linguagem e verificar o seu poderio. • Confiabilidade baixa: se uma linguagem de programação falhar em um ambiente crítico, os resultados podem ser catastróficos. • Manutenção de programas: Isso inclui correção e implementação de novas funcionalidades em programas. Se uma linguagem tem uma legibilidade ruim, então haverão problemas ao se dar continuidade na vida do software que foi desenvolvido. 6.Descreva alguns trade"offs de projeto entre a eficiência e a segurança em alguma linguagem que você conheça. R:R: Pegando o exemplo da linguagem Java, ela por exemplo faz uma verificação por tipo de dados (e referencias) que fazem parte de um vetor, o que aumenta a segurança, mas ao mesmo tempo diminui a sua eficiência. Ainda sobre vetores, o java sempre faz uma verificação sobre a quantidade de elementos dentro de um vetor, novamente provendo uma segurança maior em relação às falhas de segmentação que poderiam ocorrer, mas tal verificação torna a execução do programa mais lenta. Em suma, a linguagem tende a realizar uma série de pequenas verificações em relação a vetores, tipos de variáveis e instancias, além de verificar o uso de memória, o que acaba gerando uma maior segurança a despeito do programa, mas ao custo de uma certa lentidão na execução, principalmente se comparado com outras linguagens, como o C++ por exemplo. 7.Quais recursos principais uma linguagem de programação perfeita deveria incluir, em sua opinião? R:R: Na minha opinião, poderiam haver alguns fatores que ajudariam, tais como suporte a multimídia e principalmente suporte nativo a criação de GUI. Em muitos casos, para você criar uma interface gráfica, você tem que recorrer a bibliotecas e frameworks de terceiros. O mesmo ocorre com relação a sistemas multimídia. O problema de se implementar tal recurso é o custo de compilação (ou interpretação). Um outro problema é justamente o fato da abstração por parte da plataforma. 8.A primeira linguagem de programação de alto nível que você aprendeu era implementada com um interpretador puro, um sistema de implementação híbrido ou um compilador? (Você não necessariamente saberá isso sem pesquisar). R:R: A primeira linguagem de alto nível que aprendi é considerada de alto nível e compilada (linguagem C). Seguido de C veio o C++ e o Java, sendo a última implementada através de sistema híbrido. 9.Descreva as vantagens e desvantagens de alguns ambientes de programação que você já tenha usado. R: R: O Netbeans tem uma vantagem em relação ao Eclipse pelo fato de já conter por padrão um form builder (ferramenta para construir GUI arrastando e configurando componentes), mesmo na versão mais simples e destinada somente ao Java. A principal desvantagem do ambiente é seu alto consumo de memória e processador quando executado. Já relacionado ao ambiente de programação para iOS, é o debuger do Xcode, onde nele você tem uma completa visualização de todos os componentes(podem ser elementos visuais ou objetos criados) e suas relações, consumo de memória, energia, processador e rede em tempo real. A grande desvantagem do Xcode é sua integração com o git, simplista demais e muito limitada (praticamente inexistente). 10.Como sentenças de declaração de tipos para variáveis simples afetam a legibilidade de uma linguagem, considerando que algumas não precisam de tais declarações? R: R: A declaração do tipo da variável ajuda o programador a saber o tipo da variável, evitando erros em relação a tipos incompatíveis. 11.Escreva uma avaliação de alguma linguagem de programação que você conheça, usando os critérios descritos neste capítulo. R: R: Pegando o Java como exemplo e considerando os principais pontos: • Legibilidade e facilidade de escrita: a linguagem Java herda muitas das características das sintaxes de C e C++, o que a torna simples de ler e escrever, principalmente para pessoas já habituadas no C ou C++. Um coisa que talvez confunda os programadores no início são os wrapers dos tipos primitivos (para basicamente todo tipo primitivo há uma classe relacionada, exemplo: tipo int -> Integer (classe); tipo char -> Character (classe)). • Confiabilidade: Java tem um formalismo muito forte no que diz respeito as suas especificações, e também possui um forte sistema de captura e contorno de falhas (error exceptions). • Custo: Nos mais diferentes aspectos, podemos pontuar: • Treinamento: Pela dimensão do Java, a curva de aprendizagem torna - se muito grande. • Escrita de programas: Java possui um “apelo" desktop/web (principalmente web), o que o torna uma linguagem muito boa para tal propósito. Um lado ruim dele é tentar usá-lo para aplicações que envolvam um certo controle de hardware ou SO, onde ele não apresenta pontos fortes e acaba por limitar seu uso. • Compilar programas: Java está atrelado as características da compilação usada emsistemas híbridos. • Executar programas: A linguagem tende a fazer uma série de verificações de tipo durante o seu tempo de execução, o que pode torná - la um pouco “lerda”. Uma novidade implementada nos últimos anos foi o Just in Time, o que permite a linguagem carregar somente alguns módulos necessários durante a execução, coisa que não era feita antigamente e gerava como consequência uma execução lerda e um alto consumo de memória. • Manter programas: Java é uma linguagem relativamente fácil de se manter programas e fazer manutenção, ainda mais pelo seu “formalismo” puramente focado em OO. Mesmo com os inúmeros frameworks, uma pessoa com conhecimentos mínimos na utilização deles poderá dar manutenção em códigos sem maiores dores de cabeça. • Confiabilidade baixa a custos altos: Sistemasrelativamente críticos (sistemas com muitos acessos, para ser mais exato) usam Java pela sua robustez (exemplo: sistemas utilizados em tribunais de justiça, bancos, servidores web, etc). 12.Algumas linguagens de programação – por exemplo, Pascal – têm usado o ponto e vírgula para separar sentenças, enquanto Java os utiliza para terminar sentenças. Qual desses usos, em sua opinião, é mais natural e menos provável de resultar em erros de sintaxe? Justifique sua resposta. R:R: Ao meu ver isso está relacionado com qual linguagem a pessoa estudou primeiro. Cada linguagem pode usar uma determinada forma para indicar final da instrução, como por exemplo, o C/C++/Java onde o “;” é usado para indicar o termino de uma sentença e o Python não utiliza nenhum caractere (no caso talvez ele uso o /n para indicar o termino da sentença). Se uma pessoa começar estudando Pascal e ir para uma linguagem nova, como o C, terá que se habituar a essa nova sintaxe, sendo possível que hajam erros no início por parte do programador. Após o advento do C e com muitas linguagens usando a base da sintaxe dela, é menos provável uma pessoa ter dificuldades de aprender e assimilar uma linguagem de programação mais recente.
Compartilhar