Visione interna dei lavori svolti da un Personal Computer cosa significa ?

 Immagini e Storie delle Informazioni sul mondo Informatico :

Componente Elettronico dei Personal Computer.
Componente Elettronico dei Personal Computer.

 

 

Icone
Icone dei Programmi
Java
Linguaggio di Programmazione a Oggetti

Linguaggio di Programmazione
Linguaggio di Programmazione

 

 

 

 

SO acronimo di System Operating

Il System Operating coordina i componenti Hardware da quelli Software

Bussiness Service
Il target del Cobol
MF
Tre parole per un solo obiettivo

 

Software Rumba
Consulta i tuoi dati con un programma che li visiona a 360°.

 

Le componenti base di un Personal Computer sono la parte meccanica chiamata Hardware  e la parte di visione con dei programmi sono chiamati Software.

Il Sistema che unisce queste attività viene chiamato Sistema Operativo.

I Software  sono dei programmi che vengono sviluppati da società che si occupano di creare delle applicazioni da installare sui Personal Computer.

Tecnicamente esso è la codifica di un algoritmo in un certo linguaggio di programmazione realizzata da un programmatore nella rispettiva fase di programmazione.

In altri termini è una sequenza ordinata di istruzioni (espresse secondo un insieme di regole noto a priori) che, a partire da dei dati in ingresso, restituisce dei risultati in uscita in seguito alla loro elaborazione o manipolazione da parte dell’hardware della macchina (processore).

La società dove lavoro come Supporto Tecnico Italia con compiti di facilitare  e assistere a livello Tecnico Informatico tutti gli utenti della sede Italiana che si chiama Micro Focus (https://www.microfocus.com/) si occupa di sviluppare programmi per società finanziarie , banche , assicurazioni con il linguaggio di programmazione Cobol uno dei più vecchi linguaggi al mondo ma sempre funzionale per le grandi aziende.

Informazioni Tecniche:

Un sistema operativo (abbreviato in SO, in lingua inglese OS, “operating system”), in informatica, è un insieme di componenti software, che garantisce l’operatività di base di uncalcolatore, coordinando e gestendo le risorse hardware di processamento e memorizzazione, le periferiche, le risorse/attività software (processi) e facendo da interfaccia con l’utente, senza il quale quindi non sarebbe possibile l’utilizzo del computer stesso e dei programmi/software specifici, come applicazioni o librerie software.

È dunque un componente essenziale del sistema di elaborazione che funge da “base” al quale si appoggiano gli altri software, che dunque dovranno essere progettati e realizzatiin modo da essere riconosciuti e supportati da quel particolare sistema operativo. Assieme al processore, con cui è strettamente legato, costituisce la cosiddetta piattaforma del sistema di elaborazione.

Esempi di sistemi operativi sono il DOSWindowsUnixLinuxMac OS.

Il software è l’informazione o le informazioni utilizzate da uno o più sistemi informatici e memorizzate su uno o più supporti informatici. Tali informazioni possono essere quindi rappresentate da uno o più programmi, oppure da uno o più dati, oppure da una combinazione delle due.

Il termine si contrappone tradizionalmente a hardware (la componente fisica di un sistema di calcolo) che rende possibile l’esecuzione del software. Nel tempo sono entrati nell’uso altri termini che descrivono elementi di un computer, come il firmware. Il suffisso -ware viene usato anche in altri termini che indicano particolari tipi di programmi: in funzione del ruolo che hanno in un sistema di calcolo (per esempio middleware); del tipo di licenza con cui sono distribuiti (freewareshareware); e altro.

In ingegneria elettronica e informatica con il termine hardware si indica la parte fisica di un computer, ovvero tutte quelle parti elettroniche, meccaniche, magnetiche, ottiche che ne consentono il funzionamento (dette anche strumentario).

Più in generale il termine si riferisce a qualsiasi componente fisico di una periferica o di una apparecchiatura elettronica.

L’etimologia del vocabolo nasce dalla fusione di due termini della lingua inglesehard (duro, pesante) e ware (manufatto, oggetto), in contrapposizione con il software, la parte logica (e perciò soft, “morbida, leggera”) che compone il personal computer costuituendone insieme all’hardware le cosiddette applicazioni.

Il termine programma deve essere distinto da quello, più generico, di software; per programma si intende infatti un oggetto software che può essere caricato nella memoria di un computer ed eseguito in un nuovo processo. Altri oggetti software (per esempio le librerie) non hanno questa proprietà, ovvero non possono essere “eseguite” direttamente. Analogamente sarebbe opportuno distinguere il termine “programma” dal termine applicazione, che viene usato normalmente nella prospettiva dell’utente finale per intendere un “servizio” di cui l’utente può usufruire, a prescindere dal fatto che questo sia realizzato da un programma solo o da una collezione di programmi; una considerazione analoga si può applicare all’espressione sistema software, usata di norma per indicare esplicitamente una collezione di componenti software (programmi, librerie, file e così via) interagenti. Quindi, per PROGRAMMA si intende una sequenza logicamente ordinata di comandi, istruzioni ed operazioni.

Scrittura

Un programma per essere scritto deve rispettare la sintassi e la semantica del particolare linguaggio di programmazione scelto. Errori di scrittura vengono poi rilevati e segnalati in fase di compilazione o interpretazione. Il presupposto base per la corretta scrittura e funzionalità del programma, secondo le specifiche desiderate, è anche la corretta elaborazione a monte dell’algoritmo di risoluzione del problema da automatizzare.

Esecuzione

Un programma scritto in linguaggio assembly o in un linguaggio di programmazione ad alto livello (codice sorgente), può essere eseguito solo compilando il codice sorgente in codice oggetto ovvero traducendolo in linguaggio macchinache darà vita poi al programma eseguibile, oppure servendosi di un interprete.

Da parte del Sistema Operativo [modifica]

Nella maggior parte dei computer moderni, basati sull’architettura di von Neumann, l’esecuzione di un programma binario prevede che, sotto l’attività e il controllo del sistema operativo, il programma stesso sia inizialmente caricato inmemoria primaria (es. RAM), tipicamente a partire da una periferica di memoria di massa (o memoria secondaria), come ad esempio un disco rigido.

Viene quindi identificato il “punto d’ingresso” (entry point) del programma (cioè la prima istruzione), e il rispettivo indirizzo di memoria viene copiato in un registro del processore detto program counter.

A questo punto viene avviato nel processore, da parte dell’Unità di Controllo, un ciclo di fetch-execute che ripetutamente preleva l’istruzione “puntata” dal program counter, incrementa il program counter in modo da farlo puntare all’istruzione successiva, ed esegue l’istruzione caricata sequenzialmente nell’ordine. Si può osservare che il ciclo fetch-execute, per default, comporta dunque l’esecuzione sequenziale delle istruzioni del programma. L’istruzione corrente, tuttavia, può modificare il program counter: questa operazione corrisponde ad un’istruzione di salto goto o ad una di salto condizionato che è il meccanismo fondamentale su cui si basa l’implementazione delle strutture di controllo più evolute da parte di compilatori e interpreti.

Un programma in esecuzione è visto dal sistema operativo come un processo o insieme di processi, gestiti attraverso chiamate di sistema, e più programmi/processi possono essere eseguiti contemporaneamente attraverso l’eventualemultitasking offerto dal sistema operativo stesso e gestito dallo scheduler.

Da parte dell’hardware

Un programma scritto direttamente o convertito in linguaggio macchina può essere eseguito direttamente da un computer (inteso come hardware). Dal punto di vista utente, nei calcolatori moderni questo normalmente però non avviene perché l’esercizio delle risorse hardware (processore, memoria, ecc…) è sotto lo stretto controllo del sistema operativo che funge da piattaforma software del sistema. L’unica eccezione si verifica al momento dell’accensione del computer, quando viene fatto il boot e viene eseguito il firmware che si occupa di testare l’elettronica e di caricare il sistema operativo. Una volta che il processo di boot ha passato il controllo al sistema operativo, nessun programma può essere eseguito direttamente dall’hardware.

Macchine virtuali

Al giorno d’oggi, è raro che un programma sia adatto all’esecuzione diretta da parte di un computer inteso come solo hardware; di norma, esso richiede una macchina virtuale che comprende l’hardware del computer con l’aggiunta di uno o più livelli di software che contribuiscono a creare l’ambiente di esecuzione adatto per il programma stesso. Gli stessi programmi eseguibili richiedono di norma la presenza di un determinato sistema operativo, di determinate librerie, e così via. Benché le linee generali del funzionamento di una macchina virtuale siano talvolta piuttosto simili a quelle descritte sopra per la macchina di von Neumann, in molti casi esse se ne discostano in maniera sostanziale, introducendo numerosi concetti non presenti in tale architettura (per esempio, lo stack dei record di attivazione). Si può dire che un linguaggio di programmazione è tanto più ad alto livello quanto più la corrispondente macchina virtuale esibisce caratteristiche concettualmente distanti dai meccanismi fondamentali dell’architettura di von Neumann (o, in generale, dell’architettura hardware sottostante).

Linguaggio di programmazione

In informatica, un linguaggio di programmazione è un linguaggio formale, dotato (al pari di un qualsiasi linguaggio naturale) di un lessico, di una sintassi e di una semantica ben definiti. È utilizzabile per il controllo del comportamento di una macchina formale o di una implementazione di essa (tipicamente, un computer) ovvero in fase di programmazione di questa attraverso la scrittura del codice sorgente di un programma ad opera di un programmatore. Condizione sufficiente per un linguaggio per essere considerato un linguaggio di programmazione è l’essere Turing-completo.

Storia

Il primo linguaggio di programmazione della storia, se si esclude il linguaggio meccanico adoperato da Ada Lovelace per la programmazione della macchina di Charles Babbage, è a rigor di termini il Plankalkül di Konrad Zuse, sviluppato da lui nella Svizzera neutrale durante la seconda guerra mondiale e pubblicato nel 1946Plankalkül non venne mai realmente usato per programmare.

La programmazione dei primi elaboratori veniva fatta invece in short code[1], da cui poi si è evoluto l’assembly, che costituisce una rappresentazione simbolica del linguaggio macchina. La sola forma di controllo di flusso è l’istruzione di salto condizionato, che porta a scrivere programmi molto difficili da seguire logicamente per via dei continui salti da un punto all’altro del codice.

La maggior parte dei linguaggi di programmazione successivi cercarono di astrarsi da tale livello basilare, dando la possibilità di rappresentare strutture dati e strutture di controllo più generali e più vicine alla maniera (umana) di rappresentare i termini dei problemi per i quali ci si prefigge di scrivere programmi. Tra i primi linguaggi ad alto livello a raggiungere una certa popolarità ci fu il Fortran, creato nel 1957 da John Backus, da cui derivò successivamente ilBASIC (1964): oltre al salto condizionato, reso con l’istruzione IF, questa nuova generazione di linguaggi introduce nuove strutture di controllo di flusso come i cicli WHILE e FOR e le istruzioni CASE e SWITCH: in questo modo diminuisce molto il ricorso alle istruzioni di salto (GOTO), cosa che rende il codice più chiaro ed elegante, e quindi di più facile manutenzione.

Dopo la comparsa del Fortran nacquero una serie di altri linguaggi di programmazione storici, che implementarono una serie di idee e paradigmi innovativi: i più importanti sono l’ALGOL (1960) e il Lisp (1959). Tutti i linguaggi di programmazione oggi esistenti possono essere considerati discendenti da uno o più di questi primi linguaggi, di cui mutuano molti concetti di base; l’ultimo grande progenitore dei linguaggi moderni fu il Simula (1967), che introdusse per primo il concetto (allora appena abbozzato) di oggetto software.

Nel 1970 Niklaus Wirth pubblica il Pascal, il primo linguaggio strutturato, a scopo didattico; nel 1972 dal BCPL nascono prima il B (rapidamente dimenticato) e poi il C, che invece fu fin dall’inizio un grande successo. Nello stesso anno compare anche il Prolog, finora il principale esempio di linguaggio logico, che pur non essendo di norma utilizzato per lo sviluppo industriale del software (a causa della sua inefficienza) rappresenta una possibilità teorica estremamente affascinante.

Con i primi mini e microcomputer e le ricerche a Palo Alto, nel 1983 vede la luce Smalltalk, il primo linguaggio realmente e completamente ad oggetti, che si ispira al Simula e al Lisp: oltre a essere in uso tutt’oggi in determinati settori, Smalltalk viene ricordato per l’influenza enorme che ha esercitato sulla storia dei linguaggi di programmazione, introducendo il paradigma object-oriented nella sua prima incarnazione matura. Esempi di linguaggi object-oriented odierni sono Eiffel (1986), C++ (che esce nello stesso anno di Eiffel) e successivamente Java, classe 1995.

Concetti base

Tutti i linguaggi di programmazione esistenti sono definiti da un lessico, una sintassi ed una semantica e possiedono (almeno) questi due concetti chiave:

  • Variabile: un dato o un insieme di dati, noti o ignoti, già memorizzati o da memorizzare; ad una variabile corrisponde sempre, da qualche parte, un certo numero (fisso o variabile) di locazioni di memoria che vengono allocate, cioè riservate, per contenere i dati stessi. Molti linguaggi inoltre attribuiscono alle variabili un tipo, con differenti proprietà (stringhe di testo, numeri, liste, atomi ecc.).
  • Istruzione: un comando oppure una regola descrittiva: anche il concetto di istruzione è molto variabile fra i vari linguaggi. A prescindere dal particolare linguaggio però, ogni volta che un’istruzione viene eseguita, lo stato interno del calcolatore (che sia lo stato reale della macchina oppure un ambiente virtuale, teorico, creato dal linguaggio) cambia.

Alcuni concetti sono poi presenti nella gran parte dei linguaggi:

  • Espressione: una combinazione di variabili e costanti, unite da operatori; le espressioni sono state introdotte inizialmente per rappresentare le espressioni matematiche, ma in seguito la loro funzionalità si è estesa. Una espressione viene valutata per produrre un valore, e la sua valutazione può produrre “effetti collaterali” sul sistema e/o sugli oggetti che vi partecipano.
  • Strutture dati, meccanismi che permettono di organizzare e gestire dati complessi.
  • Strutture di controllo, che permettono di governare il flusso di esecuzione del programma, alterandolo in base al risultato o valutazione di una espressione (che può ridursi al contenuto di una variabile, o essere anche molto complessa) (cicli iterativi quali ad esempio fordowhile e strutture condizionali quali ad esempio ifswitch-case).
  • Sottoprogramma: un blocco di codice che può essere richiamato da qualsiasi altro punto del programma. In tale ambito quasi tutti linguaggi offrono funzionalità di riuso di codice accorpando cioè sequenze di istruzioni all’interno difunzioni richiamabili secondo necessità all’interno di programmi o all’interno di librerie richiamabili in ogni programma.
  • Funzionalità di input dati da tastiera e visualizzazione dati in output (stampa a video).

Il codice sorgente

Programmare in un dato linguaggio di programmazione significa generalmente scrivere uno o più semplici file di testo ASCII, chiamato codice sorgente. I font, i colori e in generale l’aspetto grafico sono irrilevanti ai fini della programmazione in sé: per questo i programmatori non usano programmi di videoscrittura ma degli editor di testo (come emacs e brief) che invece offrono funzioni avanzate di trattamento testi (espressioni regolari, sostituzioni condizionali e ricerche su file multipli, possibilità di richiamare strumenti esterni ecc). Se un dato editor è in grado di lavorare a stretto contatto con gli altri strumenti di lavoro (compilatore, linker, interprete ecc.: vedi più avanti) allora più che di semplice editor si parla di IDE o ambiente di sviluppo integrato. Va notato che alcuni linguaggi di programmazione recenti consentono anche una forma mista di programmazione, in cui alla stesura di codice sorgente ASCII si associano anche operazioni di programmazione visuale, attraverso le quali il programmatore descrive alcuni aspetti del programma disegnando a video attraverso il mouse; un’applicazione tipica di quest’ultima forma di programmazione è il disegno interattivo della GUI del programma (finestre, menù, e così via).

Per essere eseguito dal processore il codice sorgente deve essere tradotto in linguaggio macchina che è il linguaggio in cui opera la macchina a livello fisico, e questo è possibile attraverso due possibile tecniche: la compilazione e l’interpretazione.

Compilazione e interpretazione

Il codice sorgente, contenente le istruzioni da eseguire e (spesso) alcuni dati noti e costanti, può essere poi eseguito passandolo ad un interprete che eseguirà le istruzioni in esso contenute, il che è la prassi normale per i linguaggi di scripting; oppure può venire compilato, cioè tradotto in istruzioni di linguaggio macchina da un programma compilatore: il risultato è un file binario ‘eseguibile’ (codice eseguibile) che non ha bisogno di altri programmi per andare in esecuzione, ed è anche molto più veloce di un programma interpretato.

In passato, la compilazione è stata la norma per tutti i linguaggi di programmazione di uso generale; attualmente vi sono numerosi linguaggi interpretati e di uso generale, come il linguaggio Java o quelli della piattaforma .NET, che applicano un approccio ibrido fra le due soluzioni, utilizzando un compilatore per produrre del codice in un linguaggio intermedio (detto bytecode) che viene successivamente interpretato. La differenza di prestazioni tra i linguaggi interpretati e quelli compilati è stata ridotta con tecniche di compilazione just-in-time, sebbene si continui ad utilizzare i linguaggi compilati (se non addirittura l’assembly) per le applicazioni che richiedono le massime prestazioni possibili.

La compilazione

La compilazione è il processo per cui il programma, scritto in un linguaggio di programmazione ad alto livello, viene tradotto in un codice eseguibile per mezzo di un altro programma detto appunto compilatore.

La compilazione offre numerosi vantaggi, primo fra tutti il fatto di ottenere eseguibili velocissimi nella fase di run (esecuzione) adattando vari parametri di questa fase all’hardware a disposizione; ma ha lo svantaggio principale nel fatto che è necessario compilare un eseguibile diverso per ogni sistema operativo o hardware (piattaforma) sul quale si desidera rendere disponibile l’esecuzione ovvero viene a mancare la cosiddetta portabilità.

Il collegamento (linking)

Esistono principalmente due tipi differenti di collegamento: dinamico e statico.Se il programma, come spesso accade, usa delle librerie, o è composto da più moduli software, questi devono essere ‘collegati’ tra loro. Lo strumento che effettua questa operazione è detto appunto linker (“collegatore”), e si occupa principalmente di risolvere le interconnessioni tra i diversi moduli.

Collegamento statico

Tutti i moduli del programma e le librerie utilizzate vengono incluse nell’eseguibile, che risulta grande, ma contiene tutto quanto necessario per la sua esecuzione. Se si rende necessaria una modifica ad una delle librerie, per correggere un errore o un problema di sicurezza, tutti i programmi che le usano con collegamento statico devono essere ricollegati con le nuove versioni delle librerie.

Collegamento dinamico

Le librerie utilizzate sono caricate dal sistema operativo quando necessario (linking dinamico; le librerie esterne sono chiamate “DLL”, Dynamic-link libraries nei sistemi Microsoft Windows, mentre “SO” Shared Object nei sistemi Unix-like). L’eseguibile risultante è più compatto, ma dipende dalla presenza delle librerie utilizzate nel sistema operativo per poter essere eseguito.

In questo modo, le librerie possono essere aggiornate una sola volta a livello di sistema operativo, senza necessità di ricollegare i programmi. Diventa anche possibile usare diverse versioni della stessa libreria, o usare librerie personalizzate con caratteristiche specifiche per il particolare host.

Nella realizzazione di un progetto software complesso, può succedere che alcune parti del programma vengano realizzate come librerie, per comodità di manutenzione o per poterle usare in diversi programmi che fanno parte dello stesso progetto.

La complicazione aggiunta è che quando si installa un programma con collegamento dinamico è necessario verificare la presenza delle librerie che utilizza, ed eventualmente installare anche queste. I sistemi di package management, che si occupano di installare i programmi su un sistema operativo, di solito tengono traccia automaticamente di queste dipendenze.

In genere si preferisce il collegamento dinamico, in modo da creare programmi piccoli e in generale ridurre la memoria RAM occupata, assumendo che le librerie necessarie siano già presenti nel sistema, o talvolta distribuendole insieme al programma.

L’interpretazione

Un codice python

Per cercare di eliminare il problema della portabilità (la dipendenza o meno del linguaggio dalla piattaforma) si è tentato di creare altri linguaggi che si potessero basare soltanto su librerie compilate (componenti) ad hoc per ogni piattaforma, mentre il loro codice viene interpretato, e quindi non c’è la necessità di una compilazione su ogni tipologia di macchina su cui viene eseguito.[senza fonte] Il grosso difetto di questi linguaggi è la lentezza dell’esecuzione; però hanno il grosso pregio di permettere di usare lo stesso programma senza modifica su più piattaforme. Si dice in questo caso che il programma è portabile.

La perdita di prestazioni che è alla base dei linguaggi interpretati è il doppio lavoro che è affidato alla macchina che si accinge ad elaborare tale programma. Al contrario di un programma compilato, infatti, ogni istruzione viene controllata e interpretata ad ogni esecuzione da un interprete.

Si usano linguaggi interpretati nella fase di messa a punto di un programma per evitare di effettuare numerose compilazioni o invece quando si vuole creare software che svolgono operazioni non critiche che non necessitano di ottimizzazioni riguardanti velocità o dimensioni, ma che traggono più vantaggio dalla portabilità. I linguaggi di scripting e tutti quelli orientati al Web sono quasi sempre interpretati. PHP,PerlTcl/Tk e JavaScript e molti altri sono esempi concreti di interazione non vincolata alla piattaforma.

Ci sono vari tentativi per rendere i compilatori multipiattaforma creando un livello intermedio, una sorta di semi-interpretazione, come nel caso sopra menzionato di Java; d’altro canto per i linguaggi interpretati ci sono tentativi per generare delle compilazioni (o semi-compilazioni) automatiche specifiche per la macchina su cui sono eseguiti.

Esistono anche strumenti per automatizzare per quanto possibile la compilazione di uno stesso programma su diverse piattaforme, ad esempio GNU autoconf/automake, che permette di realizzare una distribuzione del codice sorgente che può essere configurata e compilata automaticamente su diverse piattaforme, in genere almeno tutti gli Unix.

Confronto tra compilazione e interpretazione

Un esempio di codice sorgente in Python. L’evidenziazione di alcune parti di codice è uno strumento comune fra i programmatori per orientarsi fra il codice.

Questi due metodi di creazione ed esecuzione di un programma presentano entrambi vantaggi e svantaggi: il maggior vantaggio della compilazione è senz’altro l’efficienza nettamente superiore in termini di prestazioni, al prezzo del restare vincolati ad una piattaforma (combinazione di architettura hardware e sistema operativo) particolare; un linguaggio interpretato invece non ha, in linea di massima, questa dipendenza ma è più lento e richiede più memoria in fase di esecuzione.

Bytecode e P-code

Una soluzione intermedia fra compilazione e interpretazione è stata introdotta nelle prime versioni di Pascal (linguaggio)(compresa quella realizzata nel 1975 dal suo inventore, Niklaus Wirth) e successivamente adottata nei linguaggii Java e Python, con il bytecode, e nei linguaggi Visual Basic e .NET di Microsoft con il P-code. In tutti e due questi casi il codice sorgente dei programmi non viene compilato in linguaggio macchina, ma in un codice intermedio “ibrido” destinato a venire interpretato al momento dell’esecuzione del programma: il motivo di questo doppio passaggio è di avere la portabilità dei linguaggi interpretati ma anche, grazie alla pre-compilazione, un interprete più semplice e quindi più veloce. Nel caso del bytecode di Java siamo di fronte a un vero linguaggio assembler, che in origine doveva essere implementato in un modello di processore reale, poi non più realizzato; alcuni microprocessori moderni, come gli ARM con Jazelle implementano molte istruzioni bytecode e sono quindi in grado di eseguire bytecode Java come normale assembler.

Tuttavia il codice intermedio è più facile sia da interpretare che da compilare: per questo motivo sia per Java che per i linguaggi .NET sono stati sviluppati i compilatori JIT (Just In Time), che al momento del lancio di un programma Java, VB o .NET compilano al volo il codice intermedio e mandano in esecuzione un normale codice macchina nativo, eliminando completamente la necessità dell’interprete e rendendo i programmi scritti in questi linguaggi veloci quasi quanto i normali programmi compilati.

Classi di linguaggi

In generale esistono circa 2500 linguaggi di programmazione più o meno noti e diffusi. Questi in primis vengono classificati in linguaggi di programmazione ad alto livello e linguaggi di programmazione a basso livello a seconda del livello di astrazione a partire dal linguaggio macchina fin verso il linguaggio logico umano. A loro volta i linguaggi possono essere classificati in linguaggi compilati e interpretati come visto sopra. Normalmente i linguaggi vengono poi distinti in tre grandi famiglie basate sul paradigma di programmazione di riferimento: i linguaggi imperativi, quelli funzionali e quelli logici.

Imperativi

Le strutture di controllo assumono la forma di istruzioni di flusso (GOTO, FOR, IF/THEN/ELSE ecc.) e il calcolo procede per iterazione piuttosto che per ricorsione. I valori delle variabili sono spesso assegnati a partire da costanti o da altre variabili (assegnamento) e raramente per passaggio di parametri (istanziazione).Nei linguaggi imperativi l’istruzione è un comando esplicito, che opera su una o più variabili oppure sullo stato interno della macchina, e le istruzioni vengono eseguite in un ordine prestabilito. Scrivere un programma in un linguaggio imperativo significa essenzialmente occuparsi di cosa la macchina deve fare per ottenere il risultato che si vuole, e il programmatore è impegnato nel mettere a punto gli algoritmi necessari a manipolare i dati.

Tipici linguaggi imperativi:

Strutturati

La programmazione strutturata è una tecnica il cui scopo è di limitare la complessità della struttura del controllo dei programmi. Il programmatore è vincolato ad usare solo le strutture di controllo canoniche definite dal Teorema di Böhm-Jacopini, ovvero la sequenza, la selezione e il ciclo, evitando le istruzioni di salto incondizionato.

Orientati ad oggetti

La programmazione a oggetti è basata su una evoluzione del concetto di tipo di dato astratto caratterizzata da incapsulamentoereditarietàpolimorfismo. Oltre a linguaggi specializzati che implementano completamente i principi di tale metodologia (come Smalltalk o Java), molti linguaggi moderni incorporano alcuni concetti della programmazione a oggetti.

Funzionali

sono basati sul concetto matematico di funzione. In un linguaggio funzionale puro l’assegnazione esplicita risulta addirittura completamente assente (si utilizza soltanto il passaggio dei parametri). In tale modello rivestono particolare importanza la ricorsione, e, come struttura dati, la lista (sequenza ordinata di elementi). Il più importante rappresentante di questa categoria è senz’altro il Lisp (LISt Processing).I linguaggi funzionali di edemeo

Dichiarativi (o logici)


La struttura di controllo principale è rappresentata dal 
cut, che è detto rosso se modifica il comportamento del programma o verde se rende solo più efficiente il calcolo, che procede per ricorsione e non per iterazione. Le variabili ricevono il loro valore per istanziazione o da altre variabili già assegnate nella clausola (unificazione) e quasi mai per assegnamento, che è usato solo in caso di calcolo diretto di espressioni numeriche.Nei linguaggi logici l’istruzione è una clausola che descrive una relazione fra i dati: programmare in un linguaggio logico significa descrivere l’insieme delle relazioni esistenti fra i dati e il risultato voluto, e il programmatore è impegnato nello stabilire in che modo i dati devono evolvere durante il calcolo. Non c’è un ordine prestabilito di esecuzione delle varie clausole, ma è compito dell’interprete trovare l’ordine giusto.

Affinché sia possibile usarli in un programma dichiarativo, tutti i normali algoritmi devono essere riformulati in termini ricorsivi e di backtracking; questo rende la programmazione con questi linguaggi una esperienza del tutto nuova e richiede di assumere un modo di pensare radicalmente diverso, perché più che calcolare un risultato si richiede di dimostrarne il valore esatto. A fronte di queste richieste, i linguaggi dichiarativi consentono di raggiungere risultati eccezionali quando si tratta di manipolare gruppi di enti in relazione fra loro.

Altre classificazioni

Dal punto di vista dei tipo di dato espresso un linguaggio può essere a tipizzazione forte o a tipizzazione debole.

Linguaggi esoterici

Linguaggi paralleli 

I moderni supercomputer e – ormai – tutti i calcolatori di fascia alta e media sono equipaggiati con più CPU. Come ovvia conseguenza, questo richiede la capacità di sfruttarle; per questo sono stati sviluppati dapprima il multithreading, cioè la capacità di lanciare più parti dello stesso programma contemporaneamente su CPU diverse, e in seguito alcuni linguaggi studiati in modo tale da poter individuare da soli, in fase di compilazione, le parti di codice da lanciare in parallelo.

Linguaggi di scripting

Il passo successivo fu quello di far accettare a questi programmi anche dei comandi di salto condizionato e delle istruzioni di ciclo, regolati da simboli associati ad un certo valore: in pratica implementare cioè l’uso di variabili. Ormai molti programmi nati per tutt’altro scopo offrono agli utenti la possibilità di programmarli in modo autonomo tramite linguaggi di scripting più o meno proprietari. Molti di questi linguaggi hanno finito per adottare una sintassi molto simile a quella del C: altri invece, come il Perl e il Python, sono stati sviluppati ex novo allo scopo. Visto che nascono tutti come feature di altri programmi, tutti i linguaggi di scripting hanno in comune il fatto di essere Linguaggi interpretati, cioè eseguiti da un altro programma (il programma madre o un suo modulo).I linguaggi di questo tipo nacquero come linguaggi batch: vale a dire liste di comandi di programmi interattivi che invece di venire digitati uno ad uno su una riga di comando, potevano essere salvati in un file, che diventava così una specie di comando composto che si poteva eseguire in modalità batch per automatizzare compiti lunghi e ripetitivi. I primi linguaggi di scripting sono stati quelli delle shell Unix; successivamente, vista l’utilità del concetto molti altri programmi interattivi iniziarono a permettere il salvataggio e l’esecuzione di file contenenti liste di comandi, oppure il salvataggio di registrazioni di comandi visuali (le cosiddette Macro dei programmi di videoscrittura, per esempio).

Valutare un linguaggio di programmazione

Non ha senso, in generale, parlare di linguaggi migliori o peggiori, o di linguaggi migliori in assoluto: ogni linguaggio nasce per affrontare una classe di problemi più o meno ampia, in un certo modo e in un certo ambito. Però, dovendo dire se un dato linguaggio sia adatto o no per un certo uso, è necessario valutare le caratteristiche dei vari linguaggi.

Caratteristiche intrinseche

Sono le qualità del linguaggio in sé, determinate dalla sua sintassi e dalla sua architettura interna. Influenzano direttamente il lavoro del programmatore, condizionandolo. Non dipendono né dagli strumenti usati (compilatore/interprete, IDE, linker) né dal sistema operativo o dal tipo di macchina.

  • Espressività: la facilità e la semplicità con cui si può scrivere un dato algoritmo in un dato linguaggio; può dipendere dal tipo di algoritmo, se il linguaggio in questione è nato per affrontare certe particolari classi di problemi. In generale se un certo linguaggio consente di scrivere algoritmi con poche istruzioni, in modo chiaro e leggibile, la sua espressività è buona.
  • Didattica: la semplicità del linguaggio e la rapidità con cui lo si può imparare. Il BASIC, per esempio, è un linguaggio facile da imparare: poche regole, una sintassi molto chiara e limiti ben definiti fra quello che è permesso e quello che non lo è. Il Pascal non solo ha i pregi del BASIC ma educa anche il neo-programmatore ad adottare uno stile corretto che evita molti errori e porta a scrivere codice migliore. Al contrario, il C non è un linguaggio didattico perché pur avendo poche regole ha una semantica molto complessa, a volte oscura, che lo rende molto efficiente ed espressivo ma richiede tempo per essere padroneggiata.
  • Leggibilità: la facilità con cui, leggendo un codice sorgente, si può capire cosa fa e come funziona. La leggibilità dipende non solo dal linguaggio ma anche dallo stile di programmazione di chi ha creato il programma: tuttavia la sintassi di un linguaggio può facilitare o meno il compito. Non è detto che un linguaggio leggibile per un profano lo sia anche per un esperto: in generale le abbreviazioni e la concisione consentono a chi già conosce un linguaggio di concentrarsi meglio sulla logica del codice senza perdere tempo a leggere, mentre per un profano è più leggibile un linguaggio molto prolisso.

A volte, un programma molto complesso e poco leggibile in un dato linguaggio può diventare assolutamente semplice e lineare se riscritto in un linguaggio di classe differente, più adatta.

  • Robustezza: è la capacità del linguaggio di prevenire, nei limiti del possibile, gli errori di programmazione. Di solito un linguaggio robusto si ottiene adottando un controllo molto stretto sui tipi di dati e una sintassi chiara e molto rigida; la segnalazione e gestione di errori comuni a runtime dovuti a dati che assumono valori imprevisti (overflowunderflow) o eccedono i limiti definiti (indici illegali per vettori o matrici) controllo dei limiti; altri sistemi sono l’implementare un garbage collector, limitando (a prezzo di una certa perdita di efficienza) la creazione autonoma di nuove entità di dati e quindi l’uso dei puntatori, che possono introdurre bug molto difficili da scoprire.

L’esempio più comune di linguaggio robusto è il Pascal, che essendo nato a scopo didattico presuppone sempre che una irregolarità nel codice sia frutto di un errore del programmatore; mentre l’assembly è l’esempio per antonomasia di linguaggio totalmente libero, in cui niente vincola il programmatore (e se scrive codice pericoloso o errato, non c’è niente che lo avverta).

  • Modularità: quando un linguaggio facilita la scrittura di parti di programma indipendenti (moduli) viene definito modulare. I moduli semplificano la ricerca e la correzione degli errori, permettendo di isolare rapidamente la parte di programma che mostra il comportamento errato e modificarla senza timore di introdurre conseguenze in altre parti del programma stesso. Questo si ripercuote positivamente sulla manutenibilità del codice; inoltre permette di riutilizzare il codice scritto in passato per nuovi programmi, apportando poche modifiche. In genere la modularità si ottiene con l’uso di sottoprogrammi (subroutine, procedure, funzioni) e con la programmazione ad oggetti.
  • Flessibilità: la possibilità di adattare il linguaggio, estendendolo con la definizione di nuovi comandi e nuovi operatori. I linguaggi classici come il BASIC, il Pascal e il Fortran non hanno questa capacità, che invece è presente nei linguaggi dichiarativi, in quelli funzionali e nei linguaggi imperativi ad oggetti più recenti come il C++ e Java.
  • Generalità: la facilità con cui il linguaggio si presta a codificare algoritmi e soluzioni di problemi in campi diversi. Di solito un linguaggio molto generale, per esempio il C, risulta meno espressivo e meno potente in una certa classe di problemi di quanto non sia un linguaggio specializzato in quella particolare nicchia, che in genere è perciò una scelta migliore finché il problema da risolvere non esce da quei confini.
  • Efficienza: la velocità di esecuzione e l’uso oculato delle risorse del sistema su cui il programma finito gira. In genere i programmi scritti in linguaggi molto astratti tendono ad essere lenti e voraci di risorse, perché lavorano entro un modello che non riflette la reale struttura dell’hardware ma è una cornice concettuale, che deve essere ricreata artificialmente; in compenso facilitano molto la vita del programmatore poiché lo sollevano dalla gestione di numerosi dettagli, accelerando lo sviluppo di nuovi programmi ed eliminando intere classi di errori di programmazione possibili. Viceversa un linguaggio meno astratto ma più vicino alla reale struttura di un computer genererà programmi molto piccoli e veloci ma a costo di uno sviluppo più lungo e difficoltoso.
  • Coerenza: l’applicazione dei principi base di un linguaggio in modo uniforme in tutte le sue parti. Un linguaggio coerente è un linguaggio facile da prevedere e da imparare, perché una volta appresi i principi base questi sono validi sempre e senza (o con poche) eccezioni.

Caratteristiche esterne

Oltre alle accennate qualità dei linguaggi, possono essere esaminate quelle degli ambienti in cui operano. Un programmatore lavora con strumenti software, la cui qualità e produttività dipende da un insieme di fattori che vanno pesati anch’essi in funzione del tipo di programmi che si intende scrivere.

  • Diffusione: il numero di programmatori nel mondo che usa il tale linguaggio. Ovviamente più è numerosa la comunità dei programmatori tanto più è facile trovare materiale, aiuto, librerie di funzioni, documentazione, consigli. Inoltre ci sono un maggior numero di software house che producono strumenti di sviluppo per quel linguaggio, e di qualità migliore.[2]
  • Standardizzazione: un produttore di strumenti di sviluppo sente sempre la tentazione di introdurre delle variazioni sintattiche o delle migliorie più o meno grandi ad un linguaggio, originando un dialetto del linguaggio in questione e fidelizzando così i programmatori al suo prodotto: ma più dialetti esistono, più la comunità di programmatori si frammenta in sottocomunità più piccole e quindi meno utili. Per questo è importante l’esistenza di uno standard per un dato linguaggio che ne garantisca certe caratteristiche, in modo da evitarne la dispersione. Quando si parla di Fortran 77Fortran 90C 99 ecc. si intende lo standard sintattico e semantico del tale linguaggio approvato nel tale anno, in genere dall’ANSI o dall’ISO.
  • Integrabilità: dovendo scrivere programmi di una certa dimensione, è molto facile trovarsi a dover integrare parti di codice precedente scritte in altri linguaggi: se un dato linguaggio di programmazione consente di farlo facilmente, magari attraverso delle procedure standard, questo è decisamente un punto a suo favore. In genere tutti i linguaggi “storici” sono bene integrabili, con l’eccezione di alcuni, come lo Smalltalk, creati più per studio teorico che per il lavoro reale di programmazione.
  • Portabilità: la possibilità che portando il codice scritto su una certa piattaforma (CPU + architettura + sistema operativo) su un’altra, questo funzioni subito, senza doverlo modificare. A questo scopo è molto importante l’esistenza di uno standard del linguaggio, anche se a volte si può contare su degli standard de facto come il C K&R o il Delphi.

 

Cobol

Il COBOL (acronimo di COmmon Business-Oriented Language, ossia, letteralmente, “linguaggio comune orientato alle applicazioni commerciali”) è uno dei primi linguaggi di programmazione ad essere stato sviluppato.

COBOL
Autore Grace Murray Hopper, William Selden, Gertrude Tierney, Howard Bromberg, Howard Discount, Vernon Reeves, Jean E. Sammet
Data di origine 1959
Ultima versione COBOL 2002 (2002)
Utilizzo General purpose
Paradigmi Programmazione procedurale, Programmazione orientata al business
Tipizzazione Forte

Storia

Progettato nel 1959, nasce ufficialmente nel 1961, grazie ad un gruppo di lavoro composto dai membri dell’industria americana e da alcune agenzie governative degli Stati Uniti con lo scopo di creare un linguaggio di programmazione adatto all’elaborazione di dati commerciali. Grace Murray Hopper ebbe un ruolo primario nello sviluppo e nella progettazione di questo linguaggio.

Dagli anni sessanta a oggi, il COBOL ha subito continue evoluzioni: negli anni 19681974 e 1985 l’American National Standards Institute (ANSI) ha definito gli standard Cobol68, Cobol74 e Cobol85, adottati anche dall’International Organization for Standardization (ISO).

Con l’ISO/IEC 1989-2002, iniziato nel 1989 e terminato nel 2002, si è giunti allo standard internazionale definitivo.

Gli applicativi Cobol, noti per la loro stabilità, sono ancora oggi (nel 2012), e lo saranno sicuramente ancora per molti anni a venire, alla base del funzionamento dei Bancomat e dell’operatività di molte banche e assicurazioni; in effetti molto spesso ciò è dovuto anche al fatto che questi applicativi sono stati sviluppati a partire dagli anni sessanta e continuamente implementati negli anni settanta e ottanta a seguito della prima diffusa informatizzazione aziendale fino agli ultimi imponenti interventi:

 

Principi di COBOL 

In generale, le istruzioni del linguaggio COBOL sono da intendere come frasi scritte in inglese, che terminano con un punto fermo. In certe situazioni, si riuniscono più istruzioni in un’unica «frase», che termina con un punto, ma in tal caso spesso si usa la virgola, e il punto e virgola per concludere le istruzioni singole.

Le istruzioni del linguaggio si compongono in linea di massima di parole chiave, costanti letterali e operatori matematici. Le parole chiave sono scritte usando lettere maiuscole (dell’alfabeto inglese) e il trattino normale (-); dal COBOL2 si possono utilizzare indifferentemente le maiuscole e le minuscole. In generale, i simboli che si possono usare nel linguaggio sono abbastanza limitati, con l’eccezione del contenuto delle costanti alfanumeriche letterali, che teoricamente potrebbero contenere qualunque simbolo (escluso quello che si usa come delimitatore) secondo le potenzialità del compilatore particolare.

I simboli disponibili nel linguaggio.
Simboli Descrizione
‘0’..’9′ cifre numeriche
‘A’..’Z’ lettere maiuscole dell’alfabeto latino
‘ ‘ spazio
‘+’ segno più
‘-‘ segno meno o trattino
‘*’ asterisco
‘/’ barra obliqua
‘$’ dollaro o segno di valuta
‘,’ virgola
‘;’ punto e virgola
‘.’ punto fermo
‘(‘ parentesi aperta
‘)’ parentesi chiusa
‘<‘ minore
‘>’ maggiore
‘<=’ minore o uguale
‘>=’ maggiore o uguale

Le parole chiave più importanti del linguaggio sono dei «verbi» imperativi, che descrivono un comando che si vuole sia eseguito. Un gruppo interessante di parole chiave è rappresentato dalle «costanti figurative», che servono a indicare verbalmente delle costanti di uso comune. Per esempio, la parola chiave ZERO rappresenta uno o più zeri, in base al contesto.

Le stringhe sono delimitate da virgolette (apici singoli) e di solito non sono previste forme di protezione per incorporare le virgolette stesse all’interno delle stringhe: per questo si possono suddividere le stringhe, concatenandole con la costante figurativa QUOTE; normalmente, comunque, la ripetizione delle virgolette viene interpretata dal compilatore come virgoletta all’interno della stringa (ad esempio: per scrivere, rispettivamente l’usolo uso’, si scrive: ‘l”uso’, ‘lo uso”’).

La gestione numerica del COBOL è speciale rispetto ai linguaggi di programmazione comuni, perché le variabili vengono dichiarate con la loro dimensione di cifre esatta, stabilendo anche la quantità di decimali e il modo in cui l’informazione deve essere gestita. In pratica, si stabilisce il modo in cui il valore deve essere rappresentato, lasciando al compilatore il compito di eseguire ogni volta tutte le conversioni necessarie. Sotto questo aspetto, un programma COBOL ha una gestione per i valori numerici molto pesante, quindi più lenta rispetto ad altri linguaggi, dove i valori numerici sono gestiti in base alle caratteristiche fisiche della CPU e le conversioni di tipo devono essere dichiarate esplicitamente.

Le variabili usate nel linguaggio sono sempre globali e come tali vanno dichiarate in una posizione apposita. Tali variabili, salvo situazioni eccezionali, fanno sempre parte di un record, inteso come una raccolta di campi di informazioni. Questa gestione particolare costringe a stabilire esattamente le dimensioni che ogni informazione deve avere se registrata nellamemoria di massa (dischi, nastri o altro) o se stampata. In un certo senso, questa caratteristica può impedire o rendere difficile l’uso di una forme di codifica dei caratteri che preveda una dimensione variabile degli stessi, considerato che i record possono essere rimappati, trattando anche valori numerici come insiemi di cifre letterali.

Questo particolare, che non è affatto di poco conto, suggerisce di usare il linguaggio per gestire dati rappresentabili con il codice ASCII tradizionale, ovvero con i primi 127 punti di codifica (da U+0000 a U+007F). Naturalmente sono disponibili compilatori che permettono di superare questo problema, ma in tal caso occorre verificare come vengono gestiti effettivamente i dati.

Le istruzioni COBOL, vengono scritte sul video nello spazio compreso tra l’ottava e la settantaduesima colonna. Il video è quindi diviso in tre aree, rispettando gli spazi stabiliti negli anni quaranta dove le colonne da uno a sei rappresentano i numeri di riga, mentre la settima colonna accetta caratteri speciali. L’area dopo la settantaduesima colonna è in genere ignorata. Le istruzioni possono essere scritte anche usando più righe, avendo l’accortezza di continuare a partire dall’area «B»; in generale non c’è bisogno di indicare esplicitamente che l’istruzione sta continuando nella riga successiva, perché si usa il punto fermo per riconoscere la loro conclusione. Tuttavia, in situazioni eccezionali, si può spezzare una parola chiave o anche una stringa letterale; in tal caso, nella settima colonna delle riga che continua, va inserito il segno -, inoltre, se si tratta di una stringa, la sua ripresa va iniziata nuovamente con le virgolette. A ogni modo, considerato che difficilmente si devono scrivere parole chiave molto lunghe e che le stringhe letterali si possono concatenare, è auspicabile che la continuazione nella riga successiva con l’indicatore nella settima colonna sia evitata del tutto.

commenti nel sorgente si indicano inserendo un asterisco nella settima colonna; se invece si mette una barra obliqua (/) si vuole richiedere un salto pagina, in fase di stampa, ammesso che il compilatore preveda questo.

Esempio di codice: Hello, world! 

000001 IDENTIFICATION DIVISION.
000002 PROGRAM-ID.     HELLOWORLD.
000003 ENVIRONMENT DIVISION.
000004 CONFIGURATION SECTION.
000005 DATA DIVISION.
000006 PROCEDURE DIVISION.
000007
000008     DISPLAY ' '
000009     DISPLAY 'HELLO, WORLD.'.
000010     STOP RUN.

Java

Java è un linguaggio di programmazione orientato agli oggetti, creato da James Gosling e altri ingegneri di Sun Microsystems. Java è un marchio registrato di Oracle.[1]

Storia

James Gosling, autore di Java

Java è stato creato a partire da ricerche effettuate alla Stanford University agli inizi degli anni Novanta. Nel 1992 nasce il linguaggio Oak (in italiano “quercia”), prodotto da Sun Microsystems e realizzato da un gruppo di esperti sviluppatori capitanati da James Gosling.Tale nome fu successivamente cambiato in Java a causa di un problema di copyright (il linguaggio di programmazione Oak esisteva già).

Per facilitare il passaggio a Java ai programmatori old-fashioned, legati in particolare a linguaggi come il C++, la sintassi di base (strutture di controllooperatori e così via) è stata mantenuta pressoché identica a quella del C++[5][6]; tuttavia, non sono state introdotte caratteristiche ritenute fonti di una complessità non necessaria a livello di linguaggio e che favoriscono l’introduzione di determinati bug durante la programmazione, come l’aritmetica dei puntatori, l’ereditarietà multipla delle classi, e l’istruzione goto.[7] Per le caratteristiche orientate agli oggetti del linguaggio ci si è ispirati al C++ e soprattutto all’Objective C.

In un primo momento Sun decise di destinare questo nuovo prodotto alla creazione di applicazioni complesse per piccoli dispositivi elettronici; fu solo nel 1993 con l’esplosione diinternet che Java iniziò a farsi notare come strumento per iniziare a programmare per internet.

Contemporaneamente Netscape Corporation annunciò la scelta di dotare il suo allora omonimo e celeberrimo browser della Java Virtual Machine (JVM). Questo segna una rivoluzione nel mondo di Internet: grazie alle applet, le pagine web diventarono interattive a livello client (ovvero le applicazioni vengono eseguite direttamente sulla macchina dell’utente di internet, e non su un server remoto). Gli utenti poterono per esempio utilizzare giochi direttamente sulle pagine web ed usufruire di chat dinamiche e interattive.

Java fu annunciato ufficialmente il 23 maggio 1995 a SunWorld.

Il 13 novembre 2006 la Sun Microsystems ha distribuito la sua implementazione del compilatore Java e della macchina virtuale (virtual machine) sotto licenza GPL. Non tutte le piattaforme java sono libere. L’ambiente Java libero si chiama IcedTea.

L’8 maggio 2007 Sun ha pubblicato anche le librerie (tranne alcune componenti non di sua proprietà) sotto licenza GPL, rendendo Java un linguaggio di programmazione la cui implementazione di riferimento è libera.

Il linguaggio è definito da un documento chiamato The Java Language Specification (spesso abbreviato JLS). La prima edizione del documento è stata pubblicata nel 1996. Da allora il linguaggio ha subito numerose modifiche e integrazioni, aggiunte di volta in volta nelle edizioni successive. Ad oggi, la versione più recente delle specifiche è la Java SE 7 Edition(quarta).

Caratteristiche

Java venne creato per soddisfare quattro scopi:

  1. essere orientato agli oggetti;
  2. essere indipendente dalla piattaforma;
  3. contenere strumenti e librerie per il networking;
  4. essere progettato per eseguire codice da sorgenti remote in modo sicuro.

Piattaforma Java

I programmi scritti in linguaggio Java, dopo una fase iniziale di compilazione con ottenimento del cosiddetto bytecode, sono destinati all’esecuzione sulla piattaforma Java attraverso una fase di interpretazione (per questo motivo il linguaggio Java è detto anche semi-interpretato) ad opera di una Java Virtual Machine e, a tempo di esecuzione, avranno accesso alle API della libreria standard. Questi due step forniscono un livello di astrazione che permette alle applicazioni di essere interamente indipendenti dal sistema hardware su cui esse saranno eseguite.

Un’implementazione della piattaforma java è il Java Runtime Environment (JRE), necessario per l’esecuzione del programma compilato, mentre per lo sviluppo dei programmi in Java a partire dal codice sorgente è necessario il Java Development Kit (JDK) che include anche il JRE.


Un’implementazione della piattaforma java è il 
Java Runtime Environment (JRE), necessario per l’esecuzione del programma compilato, mentre per lo sviluppo dei programmi in Java a partire dal codice sorgente è necessario il Java Development Kit (JDK) che include anche il JRE.I programmi scritti in linguaggio Java, dopo una fase iniziale di compilazione con ottenimento del cosiddetto bytecode, sono destinati all’esecuzione sulla piattaforma Java attraverso una fase di interpretazione (per questo motivo il linguaggio Java è detto anche semi-interpretato) ad opera di una Java Virtual Machine e, a tempo di esecuzione, avranno accesso alle API della libreria standard. Questi due step forniscono un livello di astrazione che permette alle applicazioni di essere interamente indipendenti dal sistema hardware su cui esse saranno eseguite.

Portabilità

Schema che illustra il funzionamento delbytecode sulle diverse piattaforme.

L’esecuzione di programmi scritti in Java deve avere un comportamento simile in contesti di esecuzione diversi. Per raggiungere questo obiettivo, si lavora su livelli diversi, e il primo di essi è naturalmente il linguaggio, il quale è stato progettato appositamente proprio per questo scopo. Ad esempio, esso fornisce una sintassi unificata per definire le sezioni critiche, compito che in altri linguaggi si svolge tipicamente ricorrendo a librerie di terze parti o primitive di sistema.[13] Inoltre, praticamente non lascia spazio ai comportamenti non definiti (undefined behavior) o dipendenti dall’implementazione dell’ambiente di esecuzione.

Le specifiche di linguaggio richiedono un ambiente di esecuzione che vigila sull’esecuzione del programma e che proibisce determinate operazioni che altrimenti risulterebbero insicure. Esse fanno riferimento esplicito alla Java Virtual Machine, indicandola come il destinatario tipico del bytecode prodotto dalla compilazione iniziale di un programma Java, e infatti il compilatore javac incluso nel JDK compila proprio in bytecode. Tuttavia, è possibile la compilazione verso architetture diverse, e infatti è possibile produrre codice oggetto specifico di un certo sistema operativo, servendosi di un compilatore apposito, ad esempio il GNU Compiler Collection.

In linea di principio, si dovrebbe essere in grado di scrivere il programma una sola volta e di farlo eseguire dovunque (di qui il famoso slogan di Sun: “write once, run everywhere”). La portabilità è un obiettivo tecnicamente difficile da raggiungere, e il successo di Java in questo ambito è materia di alcune controversie. Sebbene sia in effetti possibile scrivere in Java programmi che si comportano in modo consistente attraverso molte piattaforme hardware diverse, bisogna tenere presente che questi poi dipendono dalle macchine virtuali che sono, a loro volta, programmi a sé e che hanno inevitabilmente i loro bug, diversi l’una all’altra: per questo è nata una parodia dello slogan di Sun “Write once, run everywhere” (“Scrivi una volta, esegui ovunque”), che è diventato “Write once,debug anywhere” (“Scrivi una volta, correggi ovunque”).[14]

Librerie

Il linguaggio in sé definisce solo una minima parte delle librerie utilizzabili in combinazione con il linguaggio stesso. La parte restante è definita dalla piattaforma sulla quale il programma sarà eseguito.

La Oracle mette a disposizione tre piattaforme ufficiali:

In aggiunta, il programmatore può utilizzare un numero arbitrario di librerie di terze parti.

Applet


Linguaggio 
La piattaforma Java fu uno dei primi sistemi a fornire un largo supporto per l’esecuzione del codice da sorgenti remote. Un Java applet è un particolare tipo di applicazione che può essere avviata all’interno del browser dell’utente, eseguendo codice scaricato da un server web remoto. Questo codice viene eseguito in un’area (sandbox) altamente ristretta, che protegge l’utente dalla possibilità che il codice sia malevolo o abbia un comportamento non desiderato; chi pubblica il codice può applicare un certificato che usa per firmare digitalmente le applet dichiarandole “sicure”, dando loro il permesso di uscire dall’area ristretta e accedere al filesystem e al network, presumibilmente con l’approvazione e sotto il controllo dell’utente. In realtà gli applet non hanno avuto molta fortuna. Infatti presuppone che il client in cui essi vengono eseguiti abbia installata la JRE (deve eseguire il codice dell’applet). Hanno avuto fortuna le applicazioni che prevedono il cosiddetto thin-client, cioè un client ‘leggero’ che non ha bisogno di particolari strumenti per eseguire il codice remoto (a volte è necessario solo il browser).

Hello, world!

Segue il codice sorgente di un semplice programma che stampa il testo “Hello world” sulla console.

 class HelloWorld
 {
     public static void main(String[] args)
     {
         System.out.println("Hello World");
     }
 }

Come si evince un programma minimale in Java deve obbligatoriamente contenere la definizione di classe tramite la parola chiave class seguita dal nome_classe) e il metodo main o metodo principale nonché entry point del programma in cui vengono definite variabili globali, oggetti e richiamati metodi statici su variabili e/o dinamici sugli oggetti.

Nell’esempio soprastante il main contiene l’istruzione per la stampa a video della stringa Hello Word ma, pur essendo perfettamente funzionante e semplice da comprendere, non viene sfruttata la filosofia ad oggetti che viene normalmente applicata ad ogni programma scritto in Java.

Segue quindi il codice sorgente di un programma che svolge lo stesso compito del precedente, ma usando la programmazione orientata agli oggetti.

public class Messaggio
{
     private String toPrint;

     public Messaggio(String print)
     {
          this.toPrint = print;
     }

     public void print()
     {
          System.out.println(this.toPrint);
     }

     public static void main(String args[])
     {
          Messaggio ciaoMondo = new Messaggio("Hello World!");
          ciaoMondo.print();
     }
}

Il metodo main affida la stampa del messaggio a un oggetto creato apposta per questo compito, su cui è invocato il metodo dinamico print definito prima del main assieme al costruttore della classe ovvero quel particolare metodo (con ugual nome della classe) che serve per inizializzare l’attributo della classe toPrint dell’oggetto creato/istanziato nel main. I metodi definibili possono essere dichiarati privati (contrassegnati dalla parola chiave private) se richiamabili solo all’interno della stessa classe oppure pubblici (contrassegnati dalla parola chiave public) se richiamabili anche da altre classi, di tipo statico (contrassegnati dalla parola chiave static) se invocabili liberamente all’interno della classe (ad es. su variabili globali), dinamici se invocabili su oggetti.

Scrivendo nuove classi che supportano l’operazione print, si può adattare il programma per mostrare messaggi di tipi radicalmente diversi, lasciando il main pressoché immutato (basta cambiare la metà riga che segue il new). Per esempio, si può considerare un messaggio la scritta in una finestra che appare sullo schermo del computer in uso, oppure una stringa inviata su connessione di rete per apparire sulla finestra di un computer client. Oppure il programma può dialogare con l’utente sulla riga di comando o in una finestra (considerando il dialogo come un “messaggio interattivo”).

Si può modificare radicalmente il comportamento del programma con modifiche circoscritte e in punti predisposti a priori (polimorfismo): il programma può resistere ad aggiornamenti ed esigenze non previste.

Segue il codice sorgente di un programma che mostra lo stesso testo all’interno di una finestra.

import javax.swing.*;
//HelloWorld.java
public class HelloWorld 
{
   public static void main( String[] args ) 
   {
        JFrame frame = new JFrame( "Hello World!" );
        JLabel label = new JLabel("Hello World!", JLabel.CENTER );
        frame.add( label );
        frame.setSize( 300, 300 );
        frame.setVisible( true );
   }
}

Il codice proposto crea degli oggetti utilizzati per gestire l’interfaccia grafica. Viene inizialmente creata una finestra il cui titolo sarà Hello World!; all’interno di questa finestra viene inserita un’etichetta che contiene al centro la scrittaHello World!. Infine viene stabilita la dimensione della finestra e, finalmente, viene resa visibile (assieme all’etichetta che porta la scritta da visualizzare).

Anche in questo codice si fa uso della programmazione a oggetti, ma in un modo diverso: il main non conosce i meccanismi necessari per creare una interfaccia grafica sullo schermo, e questi sono decisi dalle classi JFrame e JLabel che sono state predisposte a priori (incapsulamento).

Type system

Duke, la mascotte di Java

Java è un linguaggio type safe, a tipizzazione statica, con un nominative type system, e dotato di manifest typing. In virtù di queste caratteristiche, viene generalmente considerato un linguaggio atipizzazione forte.

Il linguaggio distingue chiaramente i tipi primitivi (che definiscono valori atomici) dai tipi strutturati (che definiscono strutture dati composte).
I tipi primitivi sono detti anche tipi atomici e tipi base e sono definiti nelle specifiche di linguaggio: di ognuno sono noti l’insieme esatto dei valori ammessi e gli operatori supportati.

I tipi strutturati sono anche tipi riferimento, cioè definiscono oggetti, e sono classi o interfacce. Tra queste, le classi degli array sono definite nelle specifiche di linguaggio; tutti gli altri tipi strutturati sono “definiti dall’utente” (user-defined), cioè dal programmatore. I tipi definiti dall’utente che sono legati al linguaggio per qualche motivo sono riuniti nel package java.lang e nei suoi sottopackage; il linguaggio stabilisce per alcuni di essi (ObjectStringIterable, e altri) delle regole sintattiche o semantiche aggiuntive.

I tipi riferimento includono le classi per la gestione delle stringhe, gli array e le collezioni (liste, mappe, ecc.).

Tipi base
Tipo Descrizione Classe contenitore
byte intero con segno a 8 bit Byte
short intero con segno a 16 bit Short
int intero con segno a 32 bit Integer
long intero con segno a 64 bit Long
float virgola mobile a 32 bit singola precisione (standard IEEE 754) Float
double virgola mobile a 64 bit doppia precisione (standard IEEE 754) Double
char carattere singolo Unicode (intero senza segno a 16 bit) Character
boolean true o false Boolean

Da tutto ciò consegue che i valori dei tipi base non sono oggetti. Tuttavia, per ogni tipo base è definita una corrispondente classe (definita in gergo tipo wrapper o tipo contenitore) nel package java.lang, la quale permette di incapsulare dentro un oggetto un valore di tipo primitivo. Opportuni metodi della classe wrapper permettono di ottenere l’oggetto che incapsula un certo valore, e il valore incapsulato da un certo oggetto.

Dalla versione 5.0 in poi, sono supportati l’autoboxing e l’unboxing, che permettono di convertire da tipo primitivo a corrispondente classe wrapper e viceversa. Il compilatore, “dietro le quinte”, traduce la conversione in una opportuna invocazione a metodo sulla classe contenitore; quindi non si tratta di una vera conversione, ma di una sintassi comoda che “nasconde” la creazione di un oggetto della classe wrapper.

Come molti altri linguaggi di programmazione anche Java possiede tra le strutture dati gli array (vedi array in Java).

Strutture di controllo

Sono supportate le seguenti strutture di controllo:

  • Strutture selettive: if ... else e switch, come in C
  • Strutture iterative:
    • while e do ... while come in C
    • for mutuato dal C
    • for each che agisce su un array o collezione[15]
  • La gestione delle eccezioni in Java viene gestita dalla sintassi try ... catch ... finally simile a quella del C++.

Al di là dei costrutti per la programmazione ad oggetti il resto della sintassi di Java è detta like C, cioè derivata o simile a quella del linguaggio C.

Orientamento agli oggetti

Nel linguaggio Java, gli oggetti sono dotati di campi (definiti anche attributi o variabili di istanza o di esemplare) e di metodi. I metodi sono abitualmente usati per implementare agevolmente molti altri costrutti che alcuni altri linguaggi forniscono nativamente, come la gestione degli eventi (implementata attraverso i listeners) o delle proprietà (implementata tramite gli accessor methods e, più in generale, con oggetti JavaBeans).Java è un linguaggio object-oriented. L’idea che sta alla base della OOP è di rappresentare le entità reali o astratte, che determinano le dinamiche del problema risolto dal software, sotto forma di entità unitarie, dotate di specifiche d’uso e di funzionamento definite a priori, e chiamate oggetti. Le specifiche che definiscono le caratteristiche di queste unità (e in base alla quale le stesse vengono create o, in gergo, istanziate) sono chiamate classi.
Java tuttavia non è un linguaggio ad oggetti puro, ma solamente object oriented (orientato agli oggetti) (ad esempio, i valori dei tipi primitivi non sono oggetti).

In Java non esistono le funzioni: i blocchi di codice che “non appartengono a nessun oggetto” sono implementati come metodi statici di una certa classe (quindi sempre metodi).

In Java si pone un forte accento sulla distinzione tra interfaccia e implementazione di una classe o oggetto: la prima è l’insieme delle specifiche pubbliche di cui gli utilizzatori di un certo oggetto possono servirsi, mentre la seconda è l’insieme delle strutture interne e delle istruzioni eseguibili che, nel complesso, adempiono a tali specifiche. Il termine interfaccia è usato anche in un’altra accezione, spiegata nel seguito.

Ereditarietà

Esempio di polimorfismo: dalla base comune Shape discendono molti tipi differenti, dotati di comportamenti diversi

Exquisite-kfind.png Per approfondire, vedi Ereditarietà (informatica).

È supportata l’ereditarietà tra tipi. Questo permette di stabilire la gerarchia delle classi che compongono un programma. Il linguaggio impone che a capo della gerarchia ci sia la nota classejava.lang.Object.

In Java non esiste ereditarietà multipla tra classi.[17] Da un lato, questo vincolo permette di avere una gerarchia di classi lineare e previene gli svantaggi introdotti dall’ereditarietà multipla. Dall’altro, esso viene agevolmente superato facendo ricorso alle interfacce, ovvero a tipi analoghi alle classi, ma progettati apposta per essere estesi e soggetti a determinate restrizioni imposte dal linguaggio.[18][19] Di conseguenza esse forniscono alcuni vantaggi dell’ereditarietà multipla (come la possibilità che uno stesso oggetto appartenga a tipi diversi tra loro) senza gli svantaggi (come l’ambiguità introdotta dal fatto che una classe possa ereditare implementazioni diverse di uno stesso metodo).

Dopo l’avvento di Java, l’ereditarietà singola si è gradualmente affermata come modello standard di ereditarietà nelle tecnologie object-oriented, ed è stata abbracciata, per esempio, anche dai linguaggi del framework .NET Microsoft.

Documentazione

Le specifiche di linguaggio non impongono una determinata sintassi per la documentazione dei sorgenti, tuttavia nel tempo si è imposto come formato standard quello riconosciuto dal toolJavadoc e regolato da specifiche ufficiali ben definite (seppure esterne al linguaggio). Questo standard prevede che la documentazione sia fornita all’interno di commenti inseriti direttamente nei sorgenti e dotati di una speciale formattazione, che viene ignorata dal compilatore, ma riconosciuta da tool specializzati. Ciò rende facile aggiornare la documentazione, in quanto essa accompagna direttamente l’elemento sintattico da essa marcato; inoltre, durante la lettura dei sorgenti di un programma, ciò permette di avere sott’occhio insieme le specifiche e l’implementazione dell’elemento di programma preso in considerazione.

Un altro strumento utilizzabile per la documentazione sono le annotazioni, introdotte nella terza versione delle specifiche di linguaggio. Pur avendo una sintassi formalmente differente dai commenti Javadoc, esse sono usate per lo stesso scopo, cioè fornire metadati che descrivono le entità di programma marcate. Tuttavia, mentre i commenti riportano le specifiche in maniera discorsiva (seppure strutturata), le annotazioni per loro stessa natura sono ideali per l’elaborazione tramite i tool, più che per la lettura da parte di esseri umani. Inoltre, sotto opportune condizioni, le informazioni che forniscono sono compilate insieme al codice e possono essere lette perfino a tempo di esecuzione, cosa che i commenti non possono fare.

Sunto semplificativo dei 2 linguaggi di programmazione

La differenza dei due linguaggi di programmazione più sviluppanti nel mondo per creare applicazioni e programmi chiamati con il linguaggio tecnico Software:

COBOL è:

  • Procedura di lingua
  • Semplice umano e sintassi
  • veloce nel mainframe
  • Di facile manutenzione del codice, perché la sintassi

Per contro,

Java è:

  • Object Oriented
  • Sintassi può essere complicata
  • Richiede una macchina virtuale Java per eseguire ed eseguire il bytecode compilato.

Micro Focus International plc

Micro Focus International plc è una multinazionale del software e la tecnologia dell’informazione aziendale con sede a Newbury, Berkshire, Regno Unito. L’azienda fornisce software e servizi di consulenza per i clienti l’aggiornamento dei sistemi legacy verso piattaforme più moderne. La Società è quotata alla Borsa di Londra ed è un costituente del FTSE 250 Index.

Storia della Micro Focus

La Società è stata fondata nel 1976 [4] ed è diventato Micro Focus Group nel 1983. [4] Nei suoi primi anni si concentra su prodotti COBOL. Nel 1998 la Società ha acquisito Intersolv Inc, una le applicazioni business di abilitazione, per 534.000.000 $ [5] e le attività combinate è stata ribattezzata Merant. [4] Nel 2001 l’azienda è stata scorporata da Merant con l’aiuto di Golden Gate Capital Partners e ancora una volta è diventato Micro Mettere a fuoco.  Si è quotata al London Stock Exchange nel 2005.
Nel giugno 2008 la società ha acquisito la società di software quotata NASDAQ NetManage israeliana per US 73,3 milioni dollari.
Nel luglio 2009 la Società ha acquisito Borland, uno sviluppatore di applicazioni strumenti di gestione del ciclo di vita, così come le soluzioni di qualità (compresa l’automazione strumento Test Partner) di parte di Compuware.
Nel mese di agosto 2010 la società ha scoperto che il New South Wales Police Force aveva illegalmente distribuito 16.000 copie della piattaforma ViewNow, 9.500 oltre la licenza consentito. Micro Focus ha affermato nel 2011 che il NSW Police Force, difensore civico, l’integrità della Commissione di Polizia, Servizi correttive e altre agenzie governative illegalmente utilizzato il suo software ViewNow, che viene utilizzato per accedere al database di intelligence noto come poliziotti.
La società ha sostenuto la polizia e le altre agenzie usavano 16.500 copie del proprio software su diversi computer, quando la polizia sono stati sempre e solo il diritto di 6500 licenze. Il gruppo inizialmente sostenuto 10 milioni di dollari i danni, ma in seguito è aumentato questo a 12 milioni dollari dopo aver esaminato i risultati di un giudice ha ordinato, 120.000 $ KPMG revisione dei sistemi informatici del NSW Police Force.
La polizia ha mantenuto nel corso del procedimento giudiziario che aveva pagato per una licenza di sito che ha diritto ad un numero illimitato di installazioni del software per tutti i suoi ufficiali. Nonostante questo, ha risolto la questione in tribunale nel 2012 per una somma non. Le altre agenzie precedentemente risolto la questione fuori dal tribunale, anche per le somme non ancora manifestatisi.

Micro Focus aiuta i propri clienti a ridurre in modo significativo lo sviluppo di applicazioni e costi di gestione, aumentare la flessibilità e il valore delle risorse informatiche, e gestire meglio i rischi inerenti al mainframe e lo sviluppo e l’implementazione open-sistemi. I prodotti sono organizzati in 3 principali portafogli di soluzioni: 

  1. Visual COBOL
  2. Mainframe Solution
  3. Borland

 

[banner]

Pubblicato da itpaservicepad

Supporto sui Servizi Informatici basato su una ottima esperienza a livello pubblico e privato aziendale.