0% ont trouvé ce document utile (0 vote)
55 vues15 pages

TP D'informatique

Le document présente une analyse des enseignements que la République Démocratique du Congo peut tirer de son histoire et de celle des superpuissances en matière d'informatique. Il souligne l'importance de la souveraineté numérique, de la stabilité politique, de l'éducation, et de l'exploitation responsable des ressources naturelles pour le développement technologique. Le document aborde également des exemples pratiques, tels que des scripts Python et C++, illustrant des concepts informatiques et des compétences essentielles pour les ingénieurs.

Transféré par

nehemiemuzeke09
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats DOCX, PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
55 vues15 pages

TP D'informatique

Le document présente une analyse des enseignements que la République Démocratique du Congo peut tirer de son histoire et de celle des superpuissances en matière d'informatique. Il souligne l'importance de la souveraineté numérique, de la stabilité politique, de l'éducation, et de l'exploitation responsable des ressources naturelles pour le développement technologique. Le document aborde également des exemples pratiques, tels que des scripts Python et C++, illustrant des concepts informatiques et des compétences essentielles pour les ingénieurs.

Transféré par

nehemiemuzeke09
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats DOCX, PDF, TXT ou lisez en ligne sur Scribd

UNIKIN / POLYTECHNIQUE

Prepolytechnique

Nom : Mushindikayi
Post-nom : Muzeke
Prénom : Néhémie

Professeur : Mulombo

Travail Pratique de l’Informatique

Année académique 2024-2025.

QUESTION 1 Quels sont les enseignements essentiels que la RDC peut tirer de son contexte
historique et de l’histoire de l’informatique des superpuissances ?
La République Démocratique du Congo (RDC), en analysant son propre parcours historique et
celui des superpuissances en matière d'informatique, peut tirer plusieurs enseignements cruciaux
pour son développement socio-économique et technologique. Ces enseignements se regroupent
en deux volets : leçons issues de son contexte historique et leçons issues de l'histoire de
l'informatique des superpuissances.

I. Enseignements tirés du contexte historique de la RDC


1. Valorisation de l'indépendance et de la souveraineté numérique
L’histoire politique et économique de la RDC montre les conséquences
de la dépendance vis-à-vis de puissances étrangères. La souveraineté
technologique devient donc essentielle pour éviter une nouvelle forme
de domination à travers la dépendance informatique.

2. Importance de la stabilité politique pour le développement


technologique L’instabilité chronique (guerres, corruption, faibles
institutions) a ralenti le développement technologique. La RDC doit
comprendre qu’un environnement stable et sécurisé est un préalable
au progrès numérique.

3. Nécessité d’investir dans l’éducation et la formation locale Le manque


de main-d’œuvre qualifiée limite l’innovation. L’histoire de la RDC
montre la faiblesse des politiques éducatives en matière scientifique et
technologique. Il faut investir massivement dans les STEM (sciences,
technologies, ingénierie et mathématiques).

4. Exploitation responsable des ressources naturelles Le pays regorge de


ressources (coltan, cobalt) essentielles à l’industrie informatique
mondiale. Il doit apprendre à transformer ces ressources localement et
non se contenter de les exporter à bas prix.

II. Enseignements tirés de l’histoire de l’informatique des superpuissances


1. Le rôle stratégique de l’informatique dans le développement national
Les États-Unis, la Chine, l’Union européenne ont compris que
l’informatique est un pilier de la puissance : défense, économie,
éducation, administration. La RDC doit intégrer l’informatique dans sa
stratégie de développement.

2. Investir dans la recherche et l’innovation locale Les grandes puissances


ont bâti leur avance sur des décennies de soutien à la recherche
fondamentale et appliquée. La RDC peut en tirer la leçon qu’un pays ne
peut être souverain sans ses propres centres de recherche
technologique.

3. La maîtrise des infrastructures numériques L’histoire des


superpuissances montre que contrôler les infrastructures (réseaux,
serveurs, data centers) est indispensable. La RDC doit renforcer ses
capacités internes en cybersécurité, hébergement local et connectivité.

4. La coopération internationale stratégique Les puissances utilisent aussi


la collaboration (ex. : Union européenne, accords internationaux sur les
données) pour progresser tout en préservant leurs intérêts. La RDC
peut chercher des partenariats équilibrés pour bénéficier du transfert
de technologie.

5. Anticiper les enjeux éthiques et géopolitiques du numérique La


manipulation de l’information, la surveillance de masse, l’intelligence
artificielle posent des défis éthiques. La RDC doit intégrer ces
dimensions dans sa politique numérique pour éviter une exploitation
externe de ses données et citoyens.

Voici un exemple de script Python simple simulant une analyse de trafic réseau pour détecter des
flux suspects provenant d’adresses IP étrangères. Ce script illustre comment un pays peut exercer
un contrôle stratégique numérique en surveillant ses infrastructures critiques pour détecter des
cyberattaques ou des tentatives d'espionnage.

Script Python : Analyse de trafic réseau pour détection d'intrusions


import random from ipaddress import ip_address, ip_network

Liste simulée des adresses IP observées dans le trafic


réseau
simulated_traffic = [ {"ip": "[Link]", "bytes": 500}, {"ip": "[Link]", "bytes": 1000}, {"ip":
"[Link]", "bytes": 3000}, {"ip": "[Link]", "bytes": 450}, {"ip": "[Link]", "bytes": 700},
{"ip": "[Link]", "bytes": 2500}, {"ip": "[Link]", "bytes": 2800}, {"ip":
"[Link]", "bytes": 4000}, ]

Plages d’IP internes (réseaux privés non suspects)


internal_networks = [ ip_network("[Link]/16"), ip_network("[Link]/8"),
ip_network("[Link]/12"), ]

Détection d’IP étrangères suspectes


def is_foreign(ip): ip_obj = ip_address(ip) for network in internal_networks: if ip_obj in network:
return False return True
def detect_intrusions(traffic): print("Analyse du trafic réseau...") for flow in traffic: ip =
flow["ip"] if is_foreign(ip) and flow["bytes"] > 1000: print(f"[ALERTE] Flux suspect détecté
depuis l'IP étrangère : {ip} ({flow['bytes']} octets)")
detect_intrusions(simulated_traffic)

Explication : Contrôle stratégique numérique


Ce script illustre un contrôle stratégique numérique de plusieurs façons :
1. Surveillance active : il montre comment un pays peut surveiller les
communications entrantes sur ses réseaux critiques pour identifier des
flux anormaux.

2. Détection préventive : en détectant des IP étrangères avec un volume


de données élevé, le système peut anticiper des tentatives
d’exfiltration de données ou d’intrusion.

3. Protection des infrastructures critiques : l’analyse ciblée permet de


protéger les systèmes sensibles (gouvernement, énergie,
télécommunications, défense).

4. Souveraineté numérique : cela démontre comment un État peut


exercer sa souveraineté en développant des capacités locales de
cybersécurité plutôt que de dépendre d’acteurs extérieurs.

Voici une implémentation simple d’une machine de Turing en C++, suivie d’une explication de
son rôle historique en informatique.

1. Implémentation en C++ : Simulation d’une machine de Turing


Ce programme simule une machine de Turing qui incrémente un nombre unaire (par exemple,
transforme "111" en "1111").
#include #include #include #include
using namespace std;
enum Direction { LEFT, RIGHT, STAY };
struct Transition { char writeSymbol; Direction moveDirection; string nextState; };
class TuringMachine { private: vector tape; int head; string currentState; map<pair<string, char>,
Transition> transitions; string acceptState;
public: TuringMachine(string initialState, string accept, const vector& input) :
currentState(initialState), acceptState(accept) { tape = input; tape.push_back('_'); // symbole
blanc head = 0; }
void addTransition(string state, char read, char write, Direction dir,
string next) {
transitions[{state, read}] = {write, dir, next};
}

void run() {
while (currentState != acceptState) {
char read = tape[head];
auto key = make_pair(currentState, read);

if ([Link](key) == [Link]()) {
cout << "Aucune transition trouvée. Arrêt.\n";
break;
}

Transition t = transitions[key];
tape[head] = [Link];

if ([Link] == RIGHT) head++;


else if ([Link] == LEFT) head--;
// expansion du ruban
if (head >= [Link]()) tape.push_back('_');
if (head < 0) {
[Link]([Link](), '_');
head = 0;
}

currentState = [Link];
}

cout << "Ruban final : ";


for (char c : tape) cout << c;
cout << endl;
}

};
int main() { // Ruban initial : "111" vector input = {'1', '1', '1'};
TuringMachine tm("q0", "q_accept", input);

// Transitions : lire 1 -> aller à droite jusqu'à blanc


[Link]("q0", '1', '1', RIGHT, "q0");
[Link]("q0", '_', '1', STAY, "q_accept");

[Link]();

return 0;

}
2. Rôle historique de la machine de Turing
La machine de Turing, introduite en 1936 par Alan Turing, est un modèle théorique fondamental
qui a permis de formaliser la notion de calcul. Elle a marqué l’histoire de l’informatique pour
plusieurs raisons :
Définition du calculable : elle permet de déterminer quelles fonctions peuvent être calculées par
un algorithme.
Prémices de l’ordinateur moderne : bien que théorique, la machine de Turing a inspiré
l’architecture des ordinateurs actuels.
Base de la théorie de la complexité : elle sert de référence pour classer les problèmes selon leur
difficulté algorithmique.
Concept d’universalité : une machine de Turing universelle peut simuler toute autre machine de
Turing, concept fondamental pour les langages de programmation.
Voici un projet Python complet simulant ce que demande la QUESTION 5 : génération d’un
rapport PDF automatisé à partir de données (CSV), avec graphiques matplotlib, tableaux pandas,
et exportation au format PDF. Il illustre parfaitement une compétence essentielle pour un
ingénieur en automatisation des rapports.

1. Étapes du processus (simulé ici)


Connexion à des données (ex. : Category_Sales_for_1997.csv exportée depuis Power Query)
Analyse et visualisation (graphiques et tableau)
Génération d’un PDF rapport

2. Script Python : Générateur de rapport PDF


import pandas as pd import [Link] as plt from fpdf import FPDF import os

1. Charger les données (extraites de Power Query ou


Power BI)
df = pd.read_csv('Category_Sales_for_1997.csv')
2. Création d’un histogramme groupé
[Link](figsize=(10,6)) [Link](df['CategoryName'], df['CategorySales'], color='skyblue')
[Link]('Ventes par catégorie - 1997') [Link]('Catégorie') [Link]('Ventes ($)')
[Link](rotation=45, ha='right') plt.tight_layout() [Link]('[Link]') [Link]()

3. Générer le rapport PDF


class PDFReport(FPDF): def header(self): self.set_font('Arial', 'B', 14) [Link](0, 10, 'Rapport de
Ventes - Catégories (1997)', 0, 1, 'C') [Link](5)
def chapter_title(self, title):
self.set_font('Arial', 'B', 12)
[Link](0, 10, title, 0, 1, 'L')
[Link](2)

def chapter_body(self, content):


self.set_font('Arial', '', 10)
self.multi_cell(0, 8, content)
[Link]()

def add_chart(self, image_path):


[Link](image_path, x=10, w=190)
[Link](10)

def add_table(self, dataframe):


self.set_font('Arial', 'B', 10)
col_width = self.w / 4.5
for col in [Link]:
[Link](col_width, 8, col, 1)
[Link]()
self.set_font('Arial', '', 10)
for index, row in [Link]():
for item in row:
[Link](col_width, 8, str(item), 1)
[Link]()

pdf = PDFReport() pdf.add_page() pdf.chapter_title('1. Aperçu des ventes')


pdf.chapter_body("Voici la distribution des ventes par catégorie de produits de l'année 1997.")
pdf.add_chart('[Link]')
pdf.chapter_title('2. Tableau des données') pdf.add_table(df)

4. Sauvegarder le rapport PDF


[Link]('rapport_ventes_1997.pdf') print("Rapport PDF généré avec succès.")
Nettoyage (optionnel)
[Link]('[Link]')

3. À propos des outils mentionnés (Power Query, Power BI)


Power Query : utilisé pour extraire les données du service OData Northwind.
Power BI : utilisé pour créer des visualisations interactives, comme l’histogramme groupé.

4. Pourquoi cette compétence est stratégique pour un ingénieur ?


Gain de temps : automatisation des rapports périodiques.
Réduction d’erreurs : moins de copier-coller manuel entre Excel, Power BI et Word.
Présentation claire et professionnelle : intégration directe d’analyses et de graphiques.
Transversalité : utile dans la finance, logistique, production, marketing, etc.
Voici un programme en langage C qui mesure de façon approximative la différence de temps
d'accès entre la RAM et le cache, à l’aide de boucles répétitives et d’un tableau suffisamment
grand. Ce test met en évidence le rôle crucial de la localité spatiale et de l’architecture matérielle
(cache L1/L2/RAM).

1. Code C : Test d’accès mémoire (cache vs RAM)


#include <stdio.h> #include <stdlib.h> #include <time.h>
#define SIZE_SMALL 1024 // Taille petite (cache-friendly) #define SIZE_LARGE 100 * 1024 *
1024 // Taille grande (va au-delà du cache) #define STRIDE 64 // Écart pour simuler accès non
contigu #define REPEAT 1000
double timed_access(int *array, size_t size) { volatile int sum = 0; clock_t start = clock(); for (int
r = 0; r < REPEAT; r++) { for (size_t i = 0; i < size; i += STRIDE) { sum += array[i]; } } clock_t
end = clock(); return (double)(end - start) / CLOCKS_PER_SEC; }
int main() { // Allocation d’un tableau petit (peut tenir dans le cache) int *small_array =
malloc(SIZE_SMALL * sizeof(int)); // Allocation d’un tableau grand (débordera dans la RAM)
int *large_array = malloc(SIZE_LARGE * sizeof(int));
if (!small_array || !large_array) {
printf("Erreur d'allocation mémoire.\n");
return 1;
}

for (int i = 0; i < SIZE_SMALL; i++) small_array[i] = i;


for (int i = 0; i < SIZE_LARGE; i++) large_array[i] = i;

double time_small = timed_access(small_array, SIZE_SMALL);


double time_large = timed_access(large_array, SIZE_LARGE);

printf("Temps d'accès (cache): %f s\n", time_small);


printf("Temps d'accès (RAM): %f s\n", time_large);

free(small_array);
free(large_array);

return 0;

2. Explication technique et implications matérielles


Cache vs RAM
Cache (L1/L2/L3) : mémoire ultra-rapide située près du processeur. Temps d’accès : ~1-10 ns.
RAM : mémoire principale, plus éloignée. Temps d’accès : ~100 ns ou plus.
Localité spatiale
Les processeurs lisent les données en blocs (ex. 64 octets).
En accédant à des données contiguës, on exploite le cache efficacement.
Des accès espacés ou aléatoires obligent à recharger les blocs, ce qui ralentit fortement.
Ce que montre ce programme
Les petits tableaux sont traités très rapidement, car ils tiennent dans le cache.
Les grands tableaux accèdent souvent à la RAM, ce qui ralentit les performances.

3. Application concrète
En algorithmique, il est plus performant d’accéder à la mémoire de manière séquentielle.
Les ingénieurs doivent optimiser les structures de données et les modèles d’accès mémoire pour
tirer parti des caches (par exemple, éviter les accès aléatoires dans les grandes matrices).
Voici une explication claire et structurée des concepts fondamentaux de l’architecture des
processeurs : cycle d’instruction, pipeline, et aléas (hazards).

1. Cycle d’instruction (FETCH – DECODE – EXECUTE)


C’est le processus par lequel un processeur exécute chaque instruction d’un programme. Il
comprend trois étapes principales :
Exemple : ADD R1, R2, R3 : le processeur va chercher cette instruction, la déchiffrer,
puis additionner R2 et R3 et stocker le résultat dans R1.

2. Pipeline (ou canalisation)


Le pipeline est une technique utilisée pour améliorer la performance des processeurs en exécutant
plusieurs instructions en parallèle, chacune à une étape différente.
Analogie : comme une chaîne de montage en usine.
Résultat : 1 instruction terminée par cycle après le remplissage du pipeline, ce qui
augmente considérablement la vitesse.

3. Aléas (Hazards)
Les aléas sont des problèmes qui peuvent perturber l’exécution fluide du pipeline. Il en existe
trois types :
Solutions aux aléas :
Stall (attente)
Forwarding (transfert de résultats intermédiaires)
Branch prediction (prédiction de branchement)

Conclusion
Ces concepts sont cruciaux pour comprendre les performances d’un processeur :
Le cycle FETCH-DECODE-EXECUTE explique l’exécution d’une seule instruction.
Le pipeline améliore les performances par exécution en parallèle.
Les aléas sont les limites de ce parallélisme, qu’il faut gérer intelligemment.
Voici une explication claire accompagnée d’un exemple Python comparant processus
(multiprocessing) et threads (threading) pour une tâche de calcul intensif (CPU-bound).

1. Exemple de tâche CPU-bound (calcul de nombres premiers)


Fonction commune (test primalité)
def is_prime(n): if n < 2: return False for i in range(2, int(n**0.5) + 1): if n % i == 0: return False
return True

2. Version avec threading (ne contourne pas le GIL)


import threading import time
def count_primes_thread(nums): for n in nums: is_prime(n)
if name == "main": numbers = list(range(10_000, 15_000)) t1 =
[Link](target=count_primes_thread, args=(numbers[:2500],)) t2 =
[Link](target=count_primes_thread, args=(numbers[2500:5000],)) t3 =
[Link](target=count_primes_thread, args=(numbers[5000:7500],)) t4 =
[Link](target=count_primes_thread, args=(numbers[7500:],))
start = [Link]()
[Link](); [Link](); [Link](); [Link]()
[Link](); [Link](); [Link](); [Link]()
print("Temps avec threading :", [Link]() - start, "secondes")

Résultat attendu : lenteur malgré 4 threads — le GIL empêche le vrai parallélisme


CPU.

3. Version avec multiprocessing (contourne le GIL)


import multiprocessing import time
def count_primes_process(nums): for n in nums: is_prime(n)
if name == "main": numbers = list(range(10_000, 15_000)) p1 =
[Link](target=count_primes_process, args=(numbers[:2500],)) p2 =
[Link](target=count_primes_process, args=(numbers[2500:5000],)) p3 =
[Link](target=count_primes_process, args=(numbers[5000:7500],)) p4 =
[Link](target=count_primes_process, args=(numbers[7500:],))
start = [Link]()
[Link](); [Link](); [Link](); [Link]()
[Link](); [Link](); [Link](); [Link]()
print("Temps avec multiprocessing :", [Link]() - start, "secondes")

Résultat attendu : bien plus rapide — chaque processus utilise un cœur indépendant.

4. Explication technique des différences

5. Conclusion pédagogique
Pour les tâches CPU-intensives, multiprocessing est à privilégier.
Le GIL (Global Interpreter Lock) empêche les threads Python de s’exécuter en parallèle sur
plusieurs cœurs, même s’ils semblent parallèles.
Les processus, eux, sont gérés séparément par le système d’exploitation, permettant un vrai
parallélisme multi-cœurs.
Voici les principales fonctions techniques d’un système d’exploitation (SE), élément fondamental
qui agit comme intermédiaire entre le matériel et les applications :

1. Gestion des processus


Création, planification et terminaison des processus.
Assure le multitâche : plusieurs programmes peuvent s’exécuter simultanément.
Alloue le temps CPU à chaque processus via un ordonnanceur (scheduler).
Ex. : exécuter un navigateur pendant qu’un téléchargement tourne en arrière-plan.

2. Gestion de la mémoire
Alloue la mémoire vive (RAM) aux programmes en cours.
Utilise des techniques comme :
Mémoire virtuelle
Pagination / Segmentation
Protection de mémoire pour éviter qu’un programme n’en écrase un autre.
Ex. : un programme ne peut pas accéder à la mémoire d’un autre par erreur.

3. Gestion du système de fichiers


Organisation, lecture, écriture et suppression de fichiers.
Gère l’accès aux disques durs, SSD, clés USB, etc.
Maintient la sécurité et les permissions des fichiers.
Ex. : droits d’accès « lecture seule », « exécution », « admin », etc.

4. Gestion des périphériques (Entrées/Sorties)


Interface entre les logiciels et les périphériques matériels (clavier, écran, imprimante, etc.).
Utilise des pilotes (drivers) pour chaque type de matériel.
Ex. : communication entre le processeur et une souris USB.

5. Gestion des utilisateurs et de la sécurité


Gère les comptes utilisateurs, leurs droits d’accès et la protection du système.
Met en place des mécanismes d’authentification, cryptage, isolation.
Ex. : mot de passe, pare-feu, contrôle des accès à des fichiers critiques.

6. Gestion des communications inter-processus (IPC)


Permet aux processus de communiquer et coopérer.
Utilise des techniques comme :
Pipes
Sockets
Mémoire partagée
Signaux
Ex. : un logiciel qui affiche l’état d’un téléchargement en cours.

7. Gestion de l’alimentation et des ressources


Optimisation de la consommation d’énergie (notamment pour les appareils mobiles).
Gère l’utilisation des ressources matérielles : CPU, mémoire, batterie, etc.

Conclusion
Un système d’exploitation est un chef d’orchestre technique qui :
Coordonne le matériel,
Protège les programmes,
Optimise les performances,
Garantit la sécurité et la stabilité du système.
Voici une réponse complète à la Question 10, en deux parties :
I. Importance de comprendre le terminal
Le terminal (ou ligne de commande) est un outil essentiel pour tout ingénieur ou informaticien. Il
permet d’interagir directement avec le système d’exploitation via des commandes textuelles, sans
interface graphique.
Pourquoi c’est important ?
1. Puissance et rapidité : certaines tâches (installation de logiciels,
traitement de fichiers, scripts) sont plus rapides et précises en
terminal.

2. Automatisation : permet d’écrire des scripts (Bash, PowerShell) pour


automatiser des tâches.

3. Contrôle système avancé : accès direct à des fonctions profondes


(réseaux, permissions, processus).

4. Compétence universelle : les mêmes commandes ou concepts sont


valables dans tous les OS Unix-like (Linux, macOS, serveurs distants...).

5. Développement et DevOps : Git, Docker, SSH, Python, Java, etc. sont


souvent utilisés en ligne de commande.

II. Accéder au terminal selon les systèmes d’exploitation

III. Installer WSL (Windows Subsystem for Linux) sur Windows 11


WSL permet de faire tourner un vrai Linux à l’intérieur de Windows, sans machine virtuelle.
Étapes d’installation de WSL sur Windows 11 :
1. Ouvrir PowerShell en mode administrateur
Clic droit sur le bouton Démarrer > "Windows PowerShell (Admin)"
2. Exécuter la commande suivante :
wsl --install
Cela installe WSL 2 et Ubuntu par défaut.
Redémarrez l’ordinateur si demandé.
3. Configurer Ubuntu
Après redémarrage, Ubuntu se lance automatiquement.
Vous devrez créer un nom d’utilisateur Linux et un mot de passe.
4. (Facultatif) : Installer une autre distribution
wsl --list --online wsl --install -d Debian # exemple pour Debian

Vérifier la version de WSL


wsl --status

Pourquoi WSL est important ?


Permet d’exécuter des outils Linux (gcc, git, apt, python, etc.) sur Windows.
Utile pour le développement web, l'administration système, la cybersécurité, les scripts Bash, etc.
Compatible avec VS Code via l’extension "Remote - WSL".
.

Vous aimerez peut-être aussi