Ybadoo - Soluções em Software Livre
Turmas
1º Semestre de 2026

(Poscomp, 2025) Os paradigmas de linguagens de programação vão muito além de estilos de codificação: são modelos mentais que moldam a maneira como estruturamos e resolvemos problemas. Longe de serem regras inflexíveis, funcionam como lentes que ampliam nossa percepção técnica. Quanto mais dessas perspectivas você dominar, mais clara, estratégica e criativa será sua atuação como desenvolvedor. Com base nesse entendimento, relacione a Coluna 1 à Coluna 2, associando os paradigmas de linguagens de programação às suas respectivas características.

Coluna 1

1. Imperativo.

2. Funcional.

3. Orientado a Objetos.

4. Lógico.

Coluna 2

(   ) Programação baseada na aplicação de funções matemáticas, enfatizando imutabilidade e ausência de efeitos colaterais.

(   ) Resolve problemas por meio de encadeamento de regras e fatos, utilizando mecanismos de inferência automática para encontrar soluções.

(   ) Programação centrada na modificação explícita de estados da memória por meio de comandos sequenciais e atribuições de variáveis.

(   ) Organização de programas em entidades que encapsulam dados e comportamentos, promovendo reúso e flexibilidade por meio de conceitos como herança e polimorfismo.

A ordem correta de preenchimento dos parênteses, de cima para baixo, é:

A 3 – 2 – 1 – 4.

B 2 – 4 – 3 – 1.

C 3 – 2 – 4 – 1.

D 4 – 2 – 3 – 1.

E 2 – 4 – 1 – 3.

(TRE/PI, 2009) Tipos Abstratos de Dados (TADs) são modelos que definem um conjunto de valores e as operações válidas sobre eles, independentemente da implementação concreta. Fundamentam-se na separação entre interface e implementação: o programador interage apenas com a especificação do comportamento, enquanto a estrutura interna e os algoritmos permanecem ocultos. Com base nesse conceito, analise as afirmativas a seguir sobre características e propriedades dos TADs.

A O TAD não encapsula a estrutura de dados para permitir que os usuários possam ter acesso a todas as operações disponibilizadas sobre esses dados.

B Algumas pilhas admitem serem declaradas como tipos abstratos de dados.

C Filas não permitem declaração como tipos abstratos de dados.

D São tipos de dados que escondem a sua implementação de quem o manipula; de maneira geral as operações sobre estes dados são executadas sem que se saiba como isso é feito.

E Os tipos abstratos de dados podem ser formados pela união de tipos de dados primitivos, mas não por outros tipos abstratos de dados.

(Enade, 2005) Prolog é uma linguagem de programação lógica declarativa, fundamentada na lógica de primeira ordem. Em vez de detalhar sequências de instruções, o programador modela o problema descrevendo fatos e regras sobre o domínio. A execução ocorre por unificação e retrocesso (backtracking): diante de uma consulta, o motor de inferência tenta satisfazê-la combinando-a com a base de conhecimento, testando automaticamente caminhos alternativos até deduzir uma resposta válida ou esgotar as possibilidades. Considere os seguintes predicados escritos em Prolog.

xpto([  ], R, R).
xpto([ H | A ], Y, [ H | B]) :- xpto(A, Y, B).

zpto(X, [ X | _ ]).
zpto(X, [ _ | Z ]) :- zpto(X, Z).

Com relação aos predicados escritos em Prolog apresentados, analise as assertivas abaixo e assinale V, se verdadeiras, ou F, se falsas.

(   ) A execução de xpto([1,2,3], [ ], F) conclui com sucesso instanciando F para [1,2,3].

(   ) A execução de xpto([1,2,3], [1,2,3], F) conclui sem sucesso.

(   ) A execução de zpto(5, [1,2,3]) conclui sem sucesso.

(   ) A execução de zpto(X, [1,2,3]) conclui com sucesso, instanciando X para 1.

A ordem correta de preenchimento dos parênteses, de cima para baixo, é:

A F – V – V – V.

B V – F – V – V.

C V – V – F – V.

D V – V – V – F.

E V – V – V – V.

Na ciência da computação, concorrência é a capacidade de diferentes partes ou unidades de um programa serem executadas fora de ordem ou em ordem parcial, sem afetar o resultado. Isso permite a execução paralela de unidades simultâneas, o que pode melhorar significativamente a velocidade geral de execução em sistemas multiprocessadores e multinúcleos. Em termos mais técnicos, concorrência refere-se à decomposição de um programa em componentes independentes de ordem ou parcialmente ordenados. Considere a função apresentada a seguir, apresentada na linguagem de programação Pascal, que executa de forma recursiva a pesquisa do maior elemento de um array, decompondo esse array em partes menores até ser possível realizar a comparação de dois elementos ou retornar o valor do próprio elemento.

function maior(inicio: integer; fim: integer; vetor: array of integer): integer;
var dif, meio, first, second: integer;
begin
dif := fim - inicio;
if dif > 1 then
begin
meio := dif div 2;
first := maior(inicio, inicio + meio, vetor);
second := maior(inicio + meio + 1, fim, vetor);
if first > second
then maior := first
else maior := second
end
else
begin
if dif = 0
then maior := vetor[inicio]
else
begin
if vetor[inicio] > vetor[fim]
then maior := vetor[inicio]
else maior := vetor[fim]
end;
end;
end;

Converta a função apresentada para ser executada de forma concorrente, utilizando a linguagem de programação de sua preferência, desde que a mesma tenha suporte à concorrência.

(Enade, 2025) Programação Orientada a Objetos (POO) é um paradigma que estrutura o software em torno de objetos — entidades autônomas que combinam estado (dados) e comportamento (métodos). Diferente de abordagens puramente procedurais, a POO prioriza a modelagem de sistemas como conjuntos de componentes reutilizáveis e de fácil manutenção, sustentada por três pilares fundamentais: encapsulamento, herança e polimorfismo. Dentre eles, o polimorfismo destaca-se como um dos mecanismos mais estratégicos para promover flexibilidade e extensibilidade na arquitetura de software, permitindo que diferentes implementações coexistam sob uma mesma interface. Diante desse contexto, sobre o conceito de polimorfismo em Programação Orientada a Objetos (POO), analise as assertivas abaixo e assinale V, se verdadeiras, ou F, se falsas.

(   ) Polimorfismo é a capacidade de um objeto assumir diferentes formas, permitindo que métodos com o mesmo nome comportem-se de maneira distinta em diferentes classes que compartilham uma hierarquia.

(   ) O polimorfismo em POO pode ser alcançado principalmente por meio de sobrescrita (overriding) de métodos e, em alguns contextos, também pela sobrecarga (overloading), embora esta última seja considerada polimorfismo de tempo de compilação.

(   ) Em linguagens orientadas a objetos, o polimorfismo de inclusão (ou polimorfismo por subtipo) permite que um objeto de uma subclasse seja tratado como um objeto de sua superclasse.

(   ) O polimorfismo é um mecanismo que visa aumentar a coesão e reduzir o acoplamento entre as classes, tornando o código mais flexível e extensível.

A ordem correta de preenchimento dos parênteses, de cima para baixo, é:

A V – V – V – V.

B F – V – V – V.

C V – F – V – V.

D V – V – F – V.

E V – V – V – F.

(IFC, 2026) Analise os códigos abaixo, disponibilizados nas linguagens Java e Python, que implementam a mesma lógica. Sobre o fluxo de execução com blocos de tratamento de exceções (try-catch/except-finally) e relançamento de exceções, assinale a alternativa que apresenta a saída produzida. Considere que o método/função principal captura a exceção relançada e que o bloco finally é sempre executado antes da propagação da exceção, conforme as especificações oficiais de ambas as linguagens.

class A extends Exception { }
class B extends A { }
public class Teste {
public static void metodo() throws A {
try {
throw new B();
} catch (B e) {
System.out.print("B ");
throw e;
} finally {
System.out.print("F ");
}
}
public static void main(String[] args) {
try {
metodo();
} catch (A e) {
System.out.print("A ");
}
}
}
class A(Exception):
pass
class B(A):
pass
def metodo():
try:
raise B()
except B as e:
print("B ", end="")
raise
finally:
print("F ", end="")

if __name__ == "__main__":
try:
metodo()
except A as e:
print("A ", end="")

A B F A.

B B A F.

C F B A.

D B F.

E F A.

(Enade, 2017) Considere o programa a seguir, que ilustra a criação, execução e sincronização de duas threads.

#include <stdio.h>
#include <pthread.h>
int x = 0, y = 0; // Variáveis compartilhadas
void funcao1(void *threadarg){
x = 1;
... // várias instruções
if (y == 0)
printf("1 ");
pthread_exit(0);
}
void funcao2(void *threadarg){
y = 1;
... // várias instruções
if (x == 0)
printf("2 ");
pthread_exit(0);
}
void main(){
pthread_t t1, t2;
// Cria e dispara t1 que executa funcao1
pthread_create(&t1, NULL,(void *)funcao1, NULL);
// Cria e dispara t2 que executa funcao2
pthread_create(&t2, NULL,(void *)funcao2, NULL);
// Pai espera filho terminar
pthread_join(t1, NULL);
// Pai espera filho terminar
pthread_join(t2, NULL);
}

Ao final da execução da função main, será impresso:

A Ambos os valores "1" e "2".

B O valor "1", necessariamente.

C O valor "2", necessariamente.

D O valor "1", ou o valor "2", mas nunca ambos.

E O valor "1", ou o valor "2", ou nenhum valor, mas nunca ambos.

LISP (LISt Processor), criada por John McCarthy em 1958, é a segunda linguagem de alto nível mais antiga e pioneira no paradigma funcional. Projetada para processamento simbólico e inteligência artificial, utiliza sintaxe de S-expressões (parênteses aninhados) e unifica código e dados (homoiconicidade). Sua ênfase em recursão, tipagem dinâmica e metaprogramação influenciou profundamente linguagens modernas. Mantém relevância em sistemas complexos e no ensino de fundamentos da programação funcional. Desenvolva uma função ou um conjunto de funções em LISP, que calcule uma aproximação da constante matemática e, utilizando a série:

e = 1/0! + 1/1! + 1/2! + 1/3! + ... + 1/n!

Exemplo de utilização da função a ser desenvolvida:

(print (aproxima-e 15))
2.7182817

Em linguagens de programação, o tratamento de exceções é o processo de resposta à ocorrência de exceções – condições anômalas ou excepcionais que requerem processamento especial – durante a execução de um programa. Implemente um método que valide seu parâmetro (n), lançando uma das seguintes exceções, conforme o valor do parâmetro:

  • se n for menor que zero, lançar a exceção AException;
  • se n pertencer a sequência de Fibonacci, lançar a exceção BException;
  • se n não pertencer a sequência de Fibonacci, lançar a exceção CException.

A sequência de Fibonacci é definida recursivamente pela fórmula Fn = Fn-1 + Fn-2, com F0 = 0 e F1 = 1.