La parola chiave per riflettere su queste cose è astrazione .
L'astrazione significa semplicemente ignorare deliberatamente i dettagli di un sistema in modo che tu possa pensarci come un singolo componente indivisibile quando assemblare un sistema più grande da molti sottosistemi. È inimmaginabilmente potente: scrivere un moderno programma applicativo mentre si considerano i dettagli dell'allocazione e dei registri e i transistor transistor potrebbero essere possibili in qualche modo idealizzato, ma è incomparabilmente più facile non per pensarci e basta usare invece operazioni di alto livello. Il paradigma del computing moderno si basa in modo cruciale su più livelli di astrazione: elettronica a stato solido, microprogrammazione, istruzioni macchina, linguaggi di programmazione di alto livello, API di programmazione OS e Web, framework e applicazioni programmabili dall'utente. Praticamente nessuno può comprendere l'intero sistema al giorno d'oggi, e non c'è nemmeno un percorso immaginabile attraverso il quale potremmo mai tornare a quello stato di cose.
Il rovescio dell'astrazione è la perdita di potere. Lasciando le decisioni sui dettagli a livelli più bassi, accettiamo spesso che possano essere realizzati con efficienza subottimale, poiché i livelli inferiori non hanno il "Big Picture" e possono ottimizzare il loro funzionamento solo dalla conoscenza locale e non sono (potenzialmente) intelligente come essere umano. (Di solito, per isntance, compilare l'HLL al codice macchina è spesso fatto meglio dalle macchine che persino dall'umano più esperto, dal momento che l'architettura del processore è diventata così complicata.)
La questione della sicurezza è interessante, perché i difetti e le "perdite" nell'astrazione possono spesso essere sfruttati per violare l'integrità di un sistema. Quando un'API postula che si possano chiamare i metodi A, B e C, ma solo se la condizione X è valida, è facile dimenticare la condizione ed essere impreparati per il fallout che si verifica quando la condizione viene violata. Ad esempio, il classico overflow del buffer sfrutta il fatto che scrivere in celle di memoria produce un comportamento indefinito a meno che non abbiate assegnato personalmente questo particolare blocco di memoria. L'API garantisce solo che qualcosa succederà come risultato, ma in pratica il risultato è definito dai dettagli del sistema al livello inferiore successivo - che abbiamo deliberatamente dimenticato! Finché soddisfiamo la condizione, questo non ha importanza, ma in caso contrario, un attaccante che comprende intimamente entrambi i livelli può di solito dirigere il comportamento dell'intero sistema come desiderato e causare cose brutte.
Il caso dei bug di allocazione della memoria è particolarmente negativo perché è stato davvero difficile gestire la memoria manualmente senza un singolo errore in un sistema di grandi dimensioni. Questo potrebbe essere visto come un caso di astrazione fallito: sebbene sia possibile fare tutto ciò che è necessario con l'API C malloc
, è semplicemente facile abusarne. Alcune parti della comunità di programmazione ora pensano che questo fosse il posto sbagliato in cui introdurre un limite di livello nel sistema, e invece promuovere linguaggi con gestione automatica della memoria e garbage collection, che perde un po 'di energia, ma fornisce protezione contro il danneggiamento della memoria e un comportamento indefinito . In effetti, una ragione importante per usare ancora C ++ oggigiorno è proprio il fatto che ti permette di controllare esattamente quali risorse vengono acquisite e rilasciate quando. In questo modo, il principale scisma tra le lingue gestite e non gestite oggi può essere visto come un disaccordo su dove precisamente definire uno strato di astrazione.
Lo stesso può dirsi per molti altri principali paradigmi alternativi nel settore dell'informatica: il problema affiora in ogni momento dove devono essere costruiti sistemi di grandi dimensioni, perché semplicemente non siamo in grado di progettare soluzioni partendo da zero per i complessi requisiti comuni oggi. (Un punto di vista comune nell'IA di questi tempi è che il cervello umano in realtà fa lavora in questo modo - comportamento che si manifesta attraverso loop di feedback, reti massicciamente interconnesse ecc. Invece di moduli e livelli separati con interfacce semplici e astratte tra di loro e questo è il motivo per cui abbiamo avuto così poco successo nel simulare la nostra intelligenza.)