Un algoritmo appropriato aiuta davvero a migliorare la qualità e, in definitiva, l'efficienza di un programma?
Possiamo ancora produrre un programma di buona qualità senza l'algoritmo?
Un algoritmo appropriato è DEVE nella programmazione moderna?
Un algoritmo appropriato aiuta davvero a migliorare la qualità e, in definitiva, l'efficienza di un programma?
Possiamo ancora produrre un programma di buona qualità senza l'algoritmo?
Un algoritmo appropriato è DEVE nella programmazione moderna?
Risposte:
Penso che questa domanda implichi una prospettiva storica.
Ai vecchi tempi (di cui non sono un testimone personale, quindi questa è solo la mia ricostruzione di quell'epoca - sentiti libero di correggermi se hai vissuto cose diverse) Lo spazio e le prestazioni di HW erano nulli rispetto a quelli di oggi. Quindi tutto ciò che la gente ha scritto doveva essere molto efficiente. Pertanto, avevano bisogno di riflettere molto e di cercare di inventare i migliori algoritmi per ottenere le prestazioni spazio / tempo necessarie per svolgere il lavoro. Un altro fattore in questo è stato il fatto che gli sviluppatori stavano lavorando principalmente su ciò che potreste chiamare infrastruttura : sistemi operativi, stack di protocolli, compilatori, driver di dispositivo, editor ecc. Tutto questo è usato molto da molte persone, quindi le prestazioni fanno davvero la differenza .
Al giorno d'oggi siamo viziati dall'incredibile HW con processori multicore e gigabyte di memoria anche in un laptop di base (diamine, anche in un telefono cellulare). Ciò significa naturalmente che in molti casi, le prestazioni - e quindi l'algoritmo - hanno smesso di essere il problema centrale, ed è più importante fornire una soluzione velocemente che fornire una soluzione rapida. OTOH abbiamo un sacco di framework che ci aiutano a risolvere i problemi e incapsulano un gran numero di algoritmi allo stesso tempo. Quindi, anche quando non stiamo pensando agli algoritmi, potremmo benissimo usarne molti in background.
Tuttavia, ci sono ancora aree in cui le prestazioni sono importanti. In queste aree devi ancora pensare molto ai tuoi algoritmi prima di scrivere il codice. Il motivo è che l'algoritmo è il centro della progettazione, determinando molte strutture di dati e relazioni nel codice circostante. E se scopri troppo tardi che il tuo algoritmo non si ridimensiona bene (ad esempio è O (n 3 ), quindi sembrava carino e veloce quando lo hai testato su 10 elementi, ma nella vita reale ne avrai milioni), è molto difficile, soggetto a errori e richiede tempo per sostituirlo nel codice di produzione. E le micro-ottimizzazioni non ti aiuteranno se l'algoritmo fondamentale non è adatto al lavoro.
Solo per sottolineare qualcosa:
Un algoritmo è esso stesso una soluzione passo-passo generale del problema. Quindi, se hai risolto il problema, hai effettivamente utilizzato un algoritmo.
Il punto più importante qui è che è necessario utilizzare algoritmi per risolvere il problema, in un modo o nell'altro. Il più delle volte è meglio pensare al tuo problema prima di passare alla programmazione: questa fase è spesso chiamata design. Ma quanto e in che modo lo farai dipende da te.
Inoltre, non dovresti mescolare il concetto di algoritmo con diagrammi di flusso (sospetto che questo accada qui). I diagrammi di flusso sono solo una rappresentazione grafica che può essere utilizzata ed è stata utilizzata nei giorni precedenti per illustrare un algoritmo. Oggigiorno è praticamente deprecato.
MODIFICARE:
Esistono davvero molti modi per rappresentare un algoritmo e il codice stesso del linguaggio di programmazione è uno di questi. Tuttavia, abbastanza spesso è molto meglio o più semplice non risolvere l'intero problema in una sola volta, ma solo un contorno e quindi riempire gli spazi vuoti mentre procedi.
Il mio preferito personale qui è lo pseudo codice, e solo per coprire una struttura astratta generale dell'algoritmo in questione - è ridicolo entrare nei dettagli con lo pseudocodice , ecco a cosa serve il vero codice.
Ma il vero codice può essere utilizzato per il contorno. Ad esempio, alle persone TDD piace progettare l'algoritmo mentre codificano e, dato che non sono in grado di risolverlo tutto in una volta, progettano uno schema dell'esecuzione del programma in codice reale e usano oggetti simulati (o funzioni, metodi .. .) come spazi vuoti da riempire in seguito.
I diagrammi di attività UML sembrano essere una moderna incarnazione di diagrammi di flusso vecchio stile con un'ulteriore notazione per le nuove cose come il polimorfismo e il multithreading. Non posso davvero dire quanto sia utile, dal momento che non li ho usati molto - lo sto solo citando per completezza.
Inoltre, se stai basando il tuo algoritmo sul passaggio da uno stato all'altro , un diagramma di stato è molto utile.
In generale, qualsiasi mezzo che devi semplicemente delineare l'idea dietro un certo algoritmo è un buon modo per andare.
Una buona analogia è che devi conoscere una ricetta prima di iniziare a cucinare. Ok, puoi modificarlo mentre procedi, ma devi ancora sapere cosa vuoi fare prima di iniziare. Se voglio fare uno stufato di agnello, farò cose molto diverse rispetto a quando voglio cuocere una pagnotta di pane.
Il codice implementa algoritmi. Cercare di scrivere codice senza aver progettato l'algoritmo è come provare a dipingere una casa prima della costruzione dei muri. Gli algoritmi sono stati un "DEVE" dall'inizio della programmazione.
Essere fluente nella tua lingua aiuta a migliorare la qualità e la produttività. E risolvere piccoli problemi algoritmici è molto più utile che ripetere le stesse cose MVC 100 volte.
Tuttavia, suppongo che ci siano altri modi per ottenere fluidità.
L'algoritmo diventerà DEVE nel moderno dominio di programmazione?
È già un "must", a meno che tu non sia un "php ninja" che scrive "cool codez". Tutte le "migliori" aziende (Google, Amazon, ecc.) Testano la tua esperienza algoritmica in un'intervista e immagino che non lo farebbero senza motivo.
Ma tornando al punto originale, dovresti costantemente metterti alla prova se vuoi migliorare. E poiché i normali lavori (alias "ora scrivono gestori CRUD per altri 100 oggetti") non sempre forniscono una buona sfida, gli algoritmi lo compensano.
Direi che è necessario almeno un'idea iniziale di un algoritmo prima di iniziare a scrivere codice. Probabilmente rivedrai la tua idea durante la codifica basata su strutture di dati ecc.
Successivamente è possibile rivedere nuovamente il codice se la profilazione suggerisce che esiste un problema di prestazioni in quella zona.
Il motivo è che è più veloce correggere gli errori prima di aver scritto il codice sbagliato.
Più prosaicamente, vengono misurate abitualmente differenze di produttività da 10 a 1 tra diversi programmatori. Quando guardi i programmatori che sono al livello di produttività 10 volte, trascorrono la minima parte del loro tempo a scrivere codice. Il tempo di digitare il codice non dovrebbe essere il collo di bottiglia. Invece trascorrono una parte maggiore del loro tempo per assicurarsi di avere requisiti diretti, pianificazione, test, ecc.
Al contrario, quando si guardano i programmatori che si immergono nel codice senza una pausa, devono inevitabilmente scrivere il codice più e più volte quando incontrano problemi completamente prevedibili e il risultato finale è meno gestibile e più difettoso. (Per inciso, sapevi che una media dell'80% del denaro speso per lo sviluppo del software è in fase di manutenzione? Rendere le cose mantenibili. Molto.)
Generalmente algoritmi e strutture di dati prima, codice più tardi. Ma dipende molto dal dominio di programmazione. Facevo molte cose di tipo matematico applicato e guardavo davvero in basso il modello di cascata allora prevalente. Questo perché gli algoritmi di livello medio-basso raramente potevano essere dati per scontati. Progetta una grande struttura attorno all'esistenza di sottosistemi non scritti, quindi scopri, nel corso del gioco, che la matematica per uno di quei sottosistemi cruciali non funziona (è instabile o altro). Quindi ho sempre pensato prima ai sottosistemi più difficili, e se c'era qualche motivo di dubbio, ho scritto e testato prima quelli. Ma per alcuni domini problematici puoi semplicemente andare avanti senza molta pianificazione.
Progettare un algoritmo in sezioni, quindi dividere tali sezioni e codificarle singolarmente. In questo modo puoi mescolare entrambi i punti di vista:
Per me, è praticamente tutto il codice. Penso che sia vero per i programmatori più produttivi. Riesco a scrivere codice con la stessa facilità con cui scrivo testo.
Per quanto possibile, provo a catturare i requisiti come test eseguibili (codice). Il design è solo una codifica di alto livello. È più veloce e più preciso catturare il design nella lingua di destinazione che catturarlo in qualche altra forma e poi tradurlo.
Ho scoperto che la maggior parte degli utenti non è in grado di riesaminare efficacemente i requisiti testuali. Funzionano bene con casi d'uso sequenziali, ma i casi d'uso non possono catturare ogni aspetto dell'interfaccia utente. La cosa migliore è di gran lunga fare un primo taglio durante l'implementazione, consentire agli utenti di provarlo, ottenere i loro commenti e modificare il codice di conseguenza.
Quando ti siedi e inizi a scrivere codice, hai in mente un algoritmo, "progettato" o no.
Se ti sedessi e avviassi la programmazione senza un algoritmo completo in mente, eseguiresti una delle seguenti operazioni:
1) schiacciare i tasti in modo casuale. Questo probabilmente produrrà un errore del compilatore
2) scrivere codice compilabile che probabilmente fa qualsiasi cosa tranne la cosa che vuoi che faccia
3) scrivere codice per risolvere piccole parti del problema e svilupparlo man mano che procedi in modo aggregato, ma non pensare davvero al futuro - quindi alla fine il problema è risolto - ma il codice non è molto efficiente e con possibilità di dover tornare indietro e perdere tempo lungo la strada
Quindi le persone di solito programmano con un algoritmo in testa. Potrebbe essere stato arricchito o motivato sulla carta o su un altro supporto.
Può essere una buona disciplina pensare al tuo attacco a un problema lontano dalla tastiera, specialmente nei tuoi primi giorni come programmatore. Come hanno notato altre risposte, man mano che acquisisci maggiore esperienza, puoi migliorare la codifica di alcuni blocchi più gestibili del problema "al volo". Tuttavia, per problemi difficili o di grandi dimensioni, è utile pensare e progettare lontano dalla tastiera: quando si lavora con il codice, è più probabile che si pensi in termini di costrutti del linguaggio e in come affrontare il compito più immediato nel problema. Considerando che pensare al problema, per esempio, con carta e penna, ti libera di più dall'aspetto linguistico del codice e ti permette di pensare a un livello più astratto e più astratto.
Devi smettere di guardare alla costruzione del software come qualcosa fondamentalmente dalla costruzione di qualsiasi altra cosa di valore. Non è. Quindi, come qualsiasi altra cosa, è sempre necessario un piano o un design ben ponderato, per quanto succintivo.
Un algoritmo appropriato aiuta davvero a migliorare la qualità e, in definitiva, l'efficienza di un programma?
Un piano / schemi costruttivi adeguati aiuta a costruire una casa di qualità in modo efficiente?
Possiamo ancora produrre un programma di buona qualità senza l'algoritmo?
Riesci a costruire una casa di buona qualità in modo efficiente senza un piano di costruzione adeguato? Secondo il Teorema della Scimmia Infinita , probabilmente, sì (proprio come un milione di scimmie che digitano a caso per l'eternità finiranno per digitare le opere complete di Shakespeare.
Un algoritmo appropriato è DEVE nella programmazione moderna?
Se non vuoi essere un codice scimmia e vuoi assicurarti di non fornire software che assomigli e funzioni come merda, sì, è un must. Ogni progetto che ho dovuto salvare (perché il codice sembrava merda non sostenibile) è invariabile iniziato con una risposta negativa a quella domanda.
In effetti, la programmazione moderna è stata l'allontanamento dall'ingegnere del software di programmazione cowboy dove la pianificazione di un qualche tipo, se necessario.
Anche quando hai a disposizione una libreria di algoritmi e strutture di dati (.ie. Boost in C ++ o la libreria di raccolte Java), devi sapere come funziona quella roba per usarla in modo appropriato e per comporla in un ragionevole, più alto- algoritmi di livello.
Non è meglio È meglio non "progettare" nulla. Questo è per le persone che non scrivono programmi. Sai, le persone con esperienza reale del problema a portata di mano. Se sei un matematico, un ingegnere o un logista, va bene, devi lavorare sul processo altrove. Ma questa non è "programmazione".
Metti al primo posto una sorta di test e benchmark.
Quindi scrivi qualcosa, qualsiasi cosa. Esegui refactor-rewrite -loop finché non esaurisci il tempo o non riesci più a migliorare.
Mentre molti sembrano pensare che uno possa fare le cose con un computer senza realmente fare nulla su un computer, penso che questo sia uno dei miti più comuni là fuori. Astronautismi di architettura.
Inoltre, non puoi ottimizzare il tuo algo prima che sia scritto.
IOW, "stai vicino al metallo".