I 7 problemi più fastidiosi nella programmazione

È stato detto che i territori inesplorati delle vecchie mappe erano spesso contrassegnati dal minaccioso avvertimento: "Ecco i draghi". Forse apocrifa, l'idea era che nessuno vagando in questi angoli sconosciuti del mondo dovrebbe farlo senza essere pronto a combattere un terrificante nemico. Poteva succedere di tutto in queste regioni misteriose, e spesso quel qualcosa non era buono.

I programmatori possono essere un po 'più civili dei cavalieri medievali, ma ciò non significa che il mondo tecnico moderno non abbia la sua parte di draghi tecnici che ci aspettano in luoghi imprevisti: problemi difficili che aspettano fino alla scadenza tra pochi minuti; complicazioni che hanno letto il manuale e sanno cosa non è ben specificato; draghi malvagi che sanno come intrufolarsi in bug rudimentali e glitch prematuri, spesso subito dopo il commit del codice.

Ce ne saranno alcuni che riposeranno tranquillamente di notte, riscaldati dalla loro ingenua sicurezza che i computer sono assolutamente prevedibili, sfornando seriamente le risposte giuste. Oh, quanto poco sanno. Nonostante tutto il duro lavoro dei progettisti di chip, sviluppatori di linguaggi e milioni di programmatori ovunque, ci sono ancora spinosi boschetti di problemi di programmazione che possono mettere in ginocchio anche i programmatori più potenti.

Qui ci sono sette degli angoli più difficili del mondo della programmazione in cui metteremmo grandi indicatori con la scritta "Here be dragons".

Multithreading

Sembrava una buona idea: suddividere il programma in sezioni indipendenti e lasciare che il sistema operativo le esegua come piccoli programmi separati. Se i processori hanno quattro, sei, otto o anche più core, perché non scrivere il codice in modo che possa avere quattro, sei, otto o più thread utilizzando tutti i core indipendentemente?

L'idea funziona, quando le parti sono in realtà completamente separate e non hanno niente a che fare l'una con l'altra. Ma una volta che devono accedere alle stesse variabili o scrivere bit negli stessi file, tutte le scommesse sono disattivate. Uno dei thread arriverà prima ai dati e non è possibile prevedere quale thread sarà.

Pertanto, creiamo monitor, semafori e altri strumenti per organizzare il pasticcio multithread. Quando lavorano, lavorano. Aggiungono semplicemente un altro livello di complessità e trasformano l'atto di memorizzare i dati in una variabile in un elemento che richiede un po 'più di riflessione.

Quando non funzionano, è puro caos. I dati non hanno senso. Le colonne non si sommano. Il denaro scompare dai conti con un puff. Sono tutti pezzi in memoria. E buona fortuna nel cercare di definire tutto ciò. La maggior parte delle volte gli sviluppatori finiscono per bloccare grossi blocchi della struttura dei dati in modo che solo un thread possa toccarli. Ciò potrebbe arginare il caos, ma solo uccidendo la maggior parte del vantaggio di avere più thread che lavorano sugli stessi dati. Potresti anche riscriverlo come un programma a "thread singolo".

Chiusure

Da qualche parte lungo la linea, qualcuno ha deciso che sarebbe stato utile passare le funzioni come se fossero dati. Questo ha funzionato bene in casi semplici, ma i programmatori hanno iniziato a rendersi conto che i problemi sorgono quando le funzioni raggiungono l'esterno di se stesse e accedono ad altri dati, spesso chiamati "variabili libere". Quale versione era quella giusta? Erano i dati quando è stata avviata la chiamata alla funzione? O è stato quando la funzione viene effettivamente eseguita? Ciò è particolarmente importante per JavaScript, dove possono esserci lunghi intervalli intermedi.

La soluzione, la "chiusura", è una delle maggiori fonti di grattacapi per i programmatori JavaScript (e ora Java e Swift). I neofiti e persino molti veterani non riescono a capire cosa viene chiuso e dove potrebbero essere i confini della cosiddetta chiusura.

Il nome non aiuta: non è come se l'accesso fosse chiuso definitivamente come un bar che annuncia l'ultima chiamata. Semmai, l'accesso è aperto ma solo attraverso un wormhole nel continuum data-tempo, uno strano meccanismo di spostamento del tempo che è destinato a generare uno spettacolo televisivo di fantascienza. Ma chiamarlo "meccanismo di accesso allo stack complesso" o "sistema di giocoleria per il controllo dei dati" sembra troppo lungo, quindi siamo bloccati con "chiusure". Non farmi iniziare sul fatto che qualcuno debba pagare per le variabili non libere.

Dati troppo grandi

Quando la RAM inizia a riempirsi, tutto inizia ad andare storto. Non importa se stai eseguendo nuove analisi statistiche dei dati dei consumatori o se stai lavorando su un vecchio foglio di calcolo noioso. Quando la macchina esaurisce la RAM, si trasforma nella cosiddetta memoria virtuale che si riversa nel disco rigido superslow. È meglio che crollare completamente o terminare il lavoro, ma il ragazzo rallenta tutto.

Il problema è che i dischi rigidi sono almeno 20 o 30 volte più lenti della RAM e le unità disco del mercato di massa sono spesso più lente. Se anche qualche altro processo sta cercando di scrivere o leggere dal disco, tutto peggiora notevolmente perché le unità possono fare solo una cosa alla volta.

L'attivazione della memoria virtuale aggrava altri problemi nascosti del software. Se ci sono problemi di threading, iniziano a rompersi molto più velocemente perché i thread che sono bloccati nella memoria virtuale del disco rigido vengono eseguiti molto più lentamente degli altri thread. Ciò dura solo un breve periodo, però, perché i fili di un tempo wallflower vengono scambiati nella memoria e gli altri fili si bloccano. Se il codice è perfetto, il risultato è semplicemente molto più lento. Se non lo è, i difetti lo mandano rapidamente in un disastro. Questo è un piccolo esempio.

Gestire questo è una vera sfida per i programmatori che lavorano con grandi pile di dati. Chiunque sia un po 'sciatto con la creazione di strutture di dati dispendiose finisce con il codice che rallenta a una scansione durante la produzione. Può funzionare bene con alcuni casi di test, ma i carichi reali lo mandano a spirale verso il fallimento.

NP-completo

Chiunque abbia una formazione universitaria in informatica conosce i misteriosi problemi racchiusi in un acronimo che è raramente enunciato: polinomio non deterministico completo, noto anche come NP-completo. I dettagli spesso richiedono un intero semestre per imparare, e anche allora, molti studenti di informatica escono con la nozione nebulosa che nessuno può risolvere questi problemi perché sono troppo difficili.

I problemi NP-complete spesso sono piuttosto difficili, se li attacchi semplicemente con la forza bruta. Il "problema del venditore ambulante", ad esempio, può richiedere un tempo esponenzialmente lungo poiché il percorso di vendita include sempre più città. La risoluzione di un "problema dello zaino" trovando un sottoinsieme di numeri che si avvicina di più a un valore N viene risolto provando tutti i possibili sottoinsiemi, che è un numero molto grande. Tutti corrono con paura di questi problemi perché sono l'esempio perfetto di uno dei più grandi spauracchi della Silicon Valley: algoritmi che non si ridimensionano.

La parte difficile è che alcuni problemi NP-complete sono facili da risolvere con un'approssimazione. Gli algoritmi non promettono la soluzione esatta, ma si avvicinano molto. Potrebbero non trovare il percorso perfetto per il venditore ambulante, ma possono arrivare a pochi punti percentuali dalla risposta giusta.

L'esistenza di queste soluzioni piuttosto buone rende solo i draghi più misteriosi. Nessuno può essere sicuro che i problemi siano veramente difficili o abbastanza facili se sei disposto a essere soddisfatto da una risposta che è abbastanza buona.

Sicurezza

“Ci sono noti noti; ci sono cose che sappiamo di sapere ", ha detto una volta in una conferenza stampa Donald Rumsfeld, il Segretario alla Difesa durante la seconda amministrazione Bush. “Sappiamo anche che esistono incognite note; vale a dire che sappiamo che ci sono alcune cose che non sappiamo. Ma ci sono anche incognite sconosciute, quelle che non sappiamo di non sapere ".

Rumsfeld stava parlando della guerra in Iraq, ma lo stesso vale per la sicurezza informatica. I problemi maggiori sono i buchi che non sappiamo nemmeno siano possibili. Tutti capiscono che dovresti rendere la tua password difficile da indovinare: questo è noto. Ma chi è mai stato detto che il tuo hardware di rete ha il proprio livello software sepolto al suo interno? La possibilità che qualcuno possa saltare l'hacking del tuo sistema operativo e invece prendere di mira questo livello segreto è uno sconosciuto sconosciuto.

La possibilità di quel tipo di hack potrebbe non esserti sconosciuta ora, ma se ce ne fossero altri? Non abbiamo idea se riusciamo a indurire i buchi di cui non sappiamo nemmeno l'esistenza. Puoi bloccare le password, ma ci sono crepe che non puoi nemmeno immaginare. Questo è il divertimento di lavorare con la sicurezza del computer. E quando si tratta di programmazione, il pensiero orientato alla sicurezza sta diventando sempre più importante. Non puoi lasciare che siano i professionisti della sicurezza a ripulire il tuo casino.

Crittografia

La crittografia sembra potente e impenetrabile quando i funzionari delle forze dell'ordine si mettono di fronte al Congresso e chiedono scappatoie ufficiali per fermarla. Il problema è che la maggior parte della crittografia è basata su una nebbiosa nuvola di incertezza. Le prove matematiche che abbiamo si basano su ipotesi incerte, come è difficile fattorizzare numeri veramente grandi o calcolare un logaritmo discreto.

Quei problemi sono davvero difficili? Nessuno ha descritto pubblicamente alcun algoritmo per infrangerli, ma ciò non significa che le soluzioni non esistano. Se trovassi un modo per origliare ogni conversazione e irrompere in una banca, lo diresti prontamente al mondo e li aiuterai a tappare i buchi? O resteresti in silenzio?

La vera sfida è utilizzare la crittografia nel nostro codice. Anche se crediamo che gli algoritmi di base siano sicuri, c'è molto lavoro da fare per destreggiarsi tra password, chiavi e connessioni. Se si commette un errore e si lascia una password non protetta, tutto si apre.

Gestione dell'identità

Tutti amano quel fumetto del New Yorker con la battuta finale: "Su Internet, nessuno sa che sei un cane". Ha anche la sua pagina Wikipedia con quattro sezioni elaborate. (Su Internet, nessuno conosce la vecchia sega sull'analisi dell'umorismo e sulla dissezione delle rane.)

La buona notizia è che l'anonimato può essere liberatorio e utile. La cattiva notizia è che non abbiamo idea di come fare altro che comunicazioni anonime. Alcuni programmatori parlano di "autenticazione a due fattori", ma quelli intelligenti passano all '"autenticazione a fattori N".

Dopo la password e forse un messaggio di testo a un cellulare, non abbiamo molto di stabile. I lettori di impronte digitali sembrano impressionanti, ma molte persone sembrano disposte a divulgare come possono essere hackerati (vedi qui, qui e qui per i principianti).

Non molto di questo è importante per il mondo delle chiacchiere inattive su Snapchat o Reddit, ma il flusso di pagine Facebook compromesse è un po 'sconcertante. Non esiste un modo semplice per gestire questioni serie come proprietà, denaro, assistenza sanitaria o praticamente qualsiasi altra cosa nella vita tranne chiacchiere senza senso. I fanbois di bitcoin amano chiacchierare su quanto possa essere solida la blockchain, ma in qualche modo le monete continuano a essere derubate (vedi qui e qui). Non abbiamo un vero metodo per gestire l'identità.

Misurazione della durezza

Naturalmente, quando si tratta di programmazione, esiste anche un modo per misurare la difficoltà di un problema? Nessuno lo sa davvero. Sappiamo che alcuni problemi sono facili da risolvere, ma è completamente diverso certificarne uno come difficile. La NP-completezza è solo una parte di un elaborato tentativo di codificare la complessità degli algoritmi e dell'analisi dei dati. La teoria è utile, ma non può offrire alcuna garanzia. Si è tentati di dire che è difficile persino sapere se un problema è difficile, ma beh, hai capito lo scherzo.

Articoli Correlati

  • Download: guida allo sviluppo della carriera per sviluppatori
  • Il potere della programmazione pigra
  • 7 cattive idee di programmazione che funzionano
  • 9 cattive abitudini di programmazione che amiamo segretamente
  • 21 tendenze di programmazione calde e 21 fredde
  • Download: guida alla sopravvivenza aziendale per programmatori professionisti
  • Download: 29 suggerimenti per avere successo come sviluppatore indipendente
  • 7 linguaggi di programmazione che amiamo odiare
  • Altre 5 lezioni senza tempo di programmazione di "barbe grigie"
  • 22 insulti che nessuno sviluppatore vuole sentire
  • 9 previsioni per il futuro della programmazione
  • Le 13 abilità di sviluppatore che devi padroneggiare ora
  • Programma il mondo: 12 tecnologie che devi conoscere ora
  • Attacco ai linguaggi di programmazione di una lettera