Programmazione di basso livello: cosa c'è dentro per me? [chiuso]


32

Per anni ho considerato di scavare in quelle che considero lingue "di basso livello". Per me questo significa C e assemblaggio. Tuttavia non ho ancora avuto tempo per questo, né è mai stato necessario.

Ora, poiché non vedo sorgere alcuna necessità, mi sento come se dovessi semplicemente programmare un certo momento in cui studierò l'argomento o abbandonare il piano per sempre.

La mia posizione

Negli ultimi 4 anni mi sono concentrato sulle "tecnologie web", che possono cambiare, e sono uno sviluppatore di applicazioni, che difficilmente cambierà.

Nello sviluppo di applicazioni, penso che l'usabilità sia la cosa più importante. Scrivi applicazioni che devono essere "consumate" dagli utenti. Più queste applicazioni sono utilizzabili, più valore hai prodotto.

Al fine di ottenere una buona usabilità, credo che le seguenti cose siano praticabili

  • Buon design : funzionalità ben concepite accessibili attraverso un'interfaccia utente ben ponderata.
  • Correttezza : il miglior design non vale nulla, se non implementato correttamente.
  • Flessibilità : un'applicazione A dovrebbe evolversi costantemente, in modo che i suoi utenti non debbano passare a un'applicazione B diversa, con nuove funzionalità che A potrebbe implementare. Le applicazioni che affrontano lo stesso problema non dovrebbero differire per funzionalità ma per filosofia.
  • Prestazioni : le prestazioni contribuiscono a una buona esperienza utente. Un'applicazione è idealmente sempre reattiva e svolge i suoi compiti in modo ragionevolmente veloce (in base alla loro frequenza). Il valore dell'ottimizzazione delle prestazioni oltre il punto in cui è evidente dall'utente è discutibile.

Penso che la programmazione a basso livello non mi aiuterà, tranne per le prestazioni. Ma scrivere un'intera app in un linguaggio di basso livello per motivi di prestazioni è un'ottimizzazione prematura per me.

La mia domanda

Cosa potrebbe insegnarmi la programmazione di basso livello, quali altre lingue non mi insegnerebbero? Mi sto perdendo qualcosa, o è solo un'abilità, che è di scarsa utilità per lo sviluppo di applicazioni? Per favore, comprendi che non sto mettendo in discussione il valore di C e assembly. È solo che nella mia vita di tutti i giorni, sono abbastanza felice che tutte le complessità di quel mondo siano astratte e gestite per me (principalmente da strati scritti in C / C ++ e assemblati stessi). Semplicemente non vedo alcun concetto, che potrebbe essere nuovo per me, solo dettagli con cui dovrei riempirmi la testa. Quindi cosa c'è dentro per me?

La mia conclusione

Grazie a tutti per le loro risposte. Devo dire che nessuno mi ha davvero sorpreso, ma almeno ora sono abbastanza sicuro che lascerò cadere quest'area di interesse fino a quando non ne avrà bisogno.
Per quanto ne sappia, scrivere assembly in questi giorni per i processori in uso nelle attuali CPU non è solo inutilmente complicato, ma rischia di tradursi in prestazioni di runtime peggiori rispetto a una controparte C. L'ottimizzazione manuale è quasi impossibile a causa di OOE, mentre non si ottengono tutti i tipi di ottimizzazioni che un compilatore può eseguire automaticamente. Inoltre, il codice è portatile, perché utilizza un piccolo sottoinsieme di comandi disponibili, oppure è ottimizzato, ma probabilmente funziona su una sola architettura.
Scrivere C non è più così necessario, come in passato. Se dovessi scrivere un'applicazione in C, userei altrettanto librerie e framework testati e consolidati, il che mi risparmierebbe l'implementazione di routine di copia di stringhe, algoritmi di ordinamento e altri tipi di cose che servono come esercizio all'università. Il mio codice verrebbe eseguito più velocemente a scapito della sicurezza del tipo. Non sono né entusiasta di reinventare la ruota nel corso del normale sviluppo di app, né di provare a eseguire il debug osservando i dump principali: D
Attualmente sto sperimentando lingue e interpreti, quindi se c'è qualcosa che vorrei pubblicare, suppongo di porterebbe un concetto funzionante su C, anche se C ++ potrebbe anche fare il trucco.
Ancora una volta, grazie a tutti per le risposte e la comprensione.


6
@TheLQ: la mia domanda non è perché usarla , ma cosa posso imparare da essa .
back2dos,

1

Risposte:


9

La programmazione di basso livello è per i casi angolari in cui è presente un requisito non immediatamente presente sui normali computer desktop. Potrebbe trattarsi di un collo di bottiglia della velocità, di un collo di bottiglia della memoria o di qualcosa di completamente diverso, ed è molto spesso molto interessante vedere cosa si può fare alla luce di questi requisiti.

Pensalo come Haikus o Limericks, dove le restrizioni lo rendono interessante.

Per darti un'idea di ciò che è possibile in ciò che sembrerebbe impossibile oggi, ecco uno dei più grandi hack di sempre. Scacchi in 1 Kb di RAM! http://users.ox.ac.uk/~uzdm0006/scans/1kchess/


1
Penso che andrò davvero per "le restrizioni lo rendono interessante". Di tutte le cose menzionate qui, questa è probabilmente la migliore. A scuola, sto programmando giochi sulla mia calcolatrice con memoria da 32kB e una CPU da 8Mhz. È stato divertente, ma non ho imparato molto da cui potrei beneficiare ora.
back2dos

Downvoter, per favore, menziona il perché?

29

Ci stavo pensando di recente. Al momento mi considero uno sviluppatore C #, il che è perfetto per la mia carriera.

Tuttavia, ogni tanto mi manca qualcosa di veramente basso livello (essenzialmente "sporcarmi le mani" facendo assemblatore o driver di dispositivo in C). Mi manca solo la programmazione. Non mi aspetto che ciò mi aiuti in modo massiccio nella mia carriera. Se i driver di dispositivo o i sistemi incorporati fanno per te, potrebbe essere di grande aiuto.

Più programma nelle lingue astratte, più mi manca in primo luogo ciò che mi ha portato ai computer: frugare intorno al computer e vedere quali contrazioni. Assembler e C sono molto adatti per colpire :)

Usando le lingue più vecchie, penso che tu sia costretto a fare praticamente tutto da solo. In C # posso fare qualcosa del genere myArray.SortBy(x=>x.Name). In nessun modo sarei in grado di farlo in C. Accetto che la lingua farà il miglior ordinamento per me. Se dovessi farlo in C, sarei in grado di tornare ai tempi dei miei moduli universitari e rivedere i miei diversi algoritmi di ordinamento e ricerca.

Quindi, penso che le lingue di livello inferiore ti aiuterebbero a rivedere tutti i pezzi dimenticati da tempo che sono stati tutti sottratti. Più una sfida personale che una carriera in progresso.


15
+1 per esprimere l'amore per curiosare nell'hardware e vedere quali contrazioni - un vero smanettone
Gary Rowe,

2
Se lo desideri, puoi scrivere tu stesso la funzione di ordinamento in C #. Puoi anche usare una funzione di libreria per ordinare in C se vuoi: gnu.org/s/libc/manual/html_node/Array-Sort-Function.html. Direi anche usando lingue più vecchie, devi fare meno cose da solo. Perché la maggior parte dei problemi è già stata risolta. Ciò non impedisce comunque alle persone di reinventare la ruota:
back2dos

15

Il mio suggerimento è di giocare con C come curiosità intellettuale. Non fare un investimento pesante perché non ne vale la pena.

Obiettivi suggeriti:

  • Aggiorna la tua memoria sulle strutture di dati e sugli algoritmi di base.
    • È solo una buona cosa da sapere, come l'algebra e la geometria.
    • Prova a fare alcuni esercizi da manuale per il college o programmare puzzle in C.
  • Un migliore apprezzamento della gerarchia di memoria (larghezza di banda) , dalla cache della CPU alla latenza di rete transoceanica. Ciò aiuterà le tue capacità di sviluppo delle applicazioni a tutti i livelli.
    • Ancora più importante, è bene conoscere gli scenari in cui un piccolo riarrangiamento poco appariscente del codice di alto livello può comportare un notevole miglioramento della velocità .
      • A volte il motivo può essere compreso solo nell'implementazione di basso livello nel contesto della gerarchia di memoria.
      • Non comprendere la causa naturale di questa possibilità porta all'ignoranza , alla paura e infine alla negazione , pensando che sia sbagliato per gli sviluppatori di alto livello attingere a questo tipo di ottimizzazione. In realtà non c'è nulla di sbagliato in questo.
  • Apprezzare l' estetica dei sistemi software basati su componenti , che consente ai componenti di basso livello sviluppati in C / C ++ / Assembly di essere utilizzati da sistemi di alto livello.
    • L'estetica è esattamente la stessa dell'usabilità del software:
      • Buon design (potente, facile da usare, ben pensato)
      • Correttezza
      • Flessibilità (estensioni e nuovi comportamenti attraverso la composizione di parti esistenti, ciascuna con uno scopo chiaramente definito)
      • Prestazioni (senza complicare l'usabilità)
    • Anche se potresti non progettare i tuoi componenti di basso livello, la tua comprensione ti aiuterà a valutare e scegliere buoni componenti da utilizzare nei tuoi progetti di alto livello.
  • Infine, apprezzare che i componenti di basso livello sono quasi sempre più complicati nelle loro implementazioni , tutt'altro che immaginabili semplicemente guardando l'interfaccia.
    • Il livello basso è sempre complicato. Una buona biblioteca nasconde la complessità senza diminuirne il potere.
    • Impara a leggere le "note tecniche" scritte dagli sviluppatori dei componenti, che sono suggerimenti per gli utenti dei componenti di livello superiore su come utilizzare al meglio i componenti.

8

se vuoi capire come funziona la macchina e non solo la macchina virtuale da cui dipende il tuo linguaggio di alto livello, allora Assembly te lo insegnerà

se non hai motivo di preoccupartene - e la maggior parte dei programmatori non lo fa in questi giorni - non preoccuparti.

migliorerà le tue basi, ma probabilmente non migliorerà le tue app web


6
C funziona altrettanto bene. La maggior parte dei concetti di C sono facilmente traducibili in linguaggio macchina. Impara C e dai una rapida occhiata all'assemblatore, e sei in buona forma.
David Thornley,

Stavo per pubblicare una risposta simile. Direi che C fornisce anche un apprezzamento per il funzionamento della macchina, soprattutto per quanto riguarda la gestione della memoria. Inoltre, molti linguaggi che astraggono la complessità della macchina sono scritti in C. Almeno, la persona avrebbe una reale comprensione di quanto siano viziati :)
Tim Post

1
@Jorg: interessante. e quante di queste CPU sono in uso commerciale attivo, rispetto a Intel x86 o 6502s?
Steven A. Lowe,

1
@ Jörg, dove trovi queste CPU?

1
@Thor: la velocità non è la domanda qui, l'educazione lo è.
Steven A. Lowe,

8

Ogni linguaggio di programmazione cambia un po 'nel modo in cui pensi alla programmazione in generale. Un esempio concreto che posso darti è quando ho iniziato a imparare haskell e all'improvviso i bit funzionali di javascript, ruby ​​e python hanno appena avuto molto più senso. Non avevo mai usato foldl in nessuno dei miei codici prima, ma dopo haskell lo vedo praticamente ovunque vedo array. Quindi è molto probabile che se impari un po 'di C diventerai molto più consapevole delle caratteristiche relative alle prestazioni di vari costrutti nella tua lingua preferita. Qualche minuto fa stavo ascoltando un discorso sulla scrittura veloce e ottimizzata di javascript e il relatore ha detto "Se è difficile farlo in C, allora sarà molto lento in javascript." Il suo intento è che javascript sia un linguaggio interpretato e che l'interprete sia scritto in C o C ++.


2
+1 per la nozione di come ogni lingua cambia il modo in cui pensi.
Sean,

7

Se non lo fai solo per divertimento, perché i geek adorano davvero avere il pieno controllo del proprio hardware, potresti almeno avere una sensazione migliore di quanto può diventare più veloce un programma se scritto in C invece di, diciamo, Java. Potresti anche imparare ad apprezzare davvero le funzionalità di linguaggi di livello superiore, come la garbage collection.


1
+1 per il divertimento geek. Anche se devo dire che non sono un fanatico. E odio l'hardware :)
back2dos

1
La differenza di velocità è generalmente irrilevante. Ciò è particolarmente vero per le app Web, in cui l'elaborazione sul lato server di solito non rappresenta il collo di bottiglia.
David Thornley,

David: sono completamente d'accordo con le app web pane e burro medio. In altri domini, la differenza può essere molto rilevante.
user281377

1
@ back2dos, se l'idea di programmare vicino all'hardware non ti piace, direi che non ti preoccupare. Sarebbe come forzarti ad imparare il latino solo perché era la base per molte lingue romanze successive.
tcrosley,

2
con una memoria sufficiente Java è più veloce o più veloce di C.

5

Evviva per curiosità!

È molto utile avere un'idea di ciò che sta realmente accadendo ai livelli più bassi di un sistema complesso, anche se non c'è alcuna logica necessità di sapere per i propri doveri quotidiani. Di gran lunga il modo migliore per fare grok a livello di bit è costruire la tua CPU. Devi pensare ai codici operativi a livello di linguaggio della macchina, capire perché i set di istruzioni ortogonali sono così buoni, le complicazioni della gestione degli interruzioni, i compromessi tra circuiti complessi rispetto al microcodice (ad esempio nelle unità di moltiplicazione) e oh, così tanto altro divertimento!

Ma questo, ovviamente, richiede il know-how elettronico e richiede molto tempo, quindi la cosa migliore da fare è giocare con una CPU a 8 bit in stile antico. Microcontrollori come l'8051 sono ancora ampiamente utilizzati e disponibili per gli appassionati. Ciò richiede ancora un po 'di know-how nell'affrontare l'elettronica e nel far illuminare i LED senza fumare, e costa $$ se non sei già attrezzato per l'elettronica.

La prossima cosa migliore dopo: scherza in un simulatore di CPU (emulatore? Ottengo questi termini confusi): esistono per Z80, 6502, 8086 ... tutti i vecchi 8 bitter. Questo potrebbe essere il più educativo e divertente per un programmatore di applicazioni che non sa quale estremità del saldatore tenere (anche se si impara abbastanza velocemente :) Come il testo viene scritto nella memoria video, come i trucchi del codice assembly aiutano con le prestazioni. .. ci sono molte cose divertenti da esplorare a questo livello.

Non sono così sicuro dell'apprendimento del C come un'altra lingua, senza una comprensione iniziale del funzionamento interno della CPU. Sapere come vengono inviati i bit tra i registri della CPU e come accedere alla memoria, aiuta enormemente a ottenere veramente puntatori e altri concetti del linguaggio C.


+1 perché questa era l'unica risposta che menzionava i puntatori. Ho pensato che sarebbe stata la risposta numero 1 e ho accettato.
Erik,

4

In una parola, divertente. Quando giocavo con l'assemblatore (dopo aver lavorato da VB a C ++, C ecc.) Era fantastico spostare i dati da una parte del processore a un'altra. È stata una bella sensazione sapere esattamente cosa stava succedendo all'interno della CPU, senza preoccuparsi di ciò che stava accadendo al di sotto di cui non sapevi. Oltre a un grande senso di libertà, puoi fare praticamente qualsiasi cosa, perché non ci sono limiti incorporati che trovi nelle lingue di livello superiore.

Inoltre, poter rivolgersi a chiunque abbia programmato in qualsiasi altra lingua e andare "bene, se non sei abbastanza hardcore ..." è stato un divertimento infantile e infantile.


4
In realtà c'è molto da fare all'interno della CPU che non si vede dall'assemblatore. La CPU esegue automaticamente operazioni come l'esecuzione fuori servizio, l'hyperthreading e la memorizzazione nella memoria. Puoi sempre andare un gradino più in basso, fino a raggiungere le particelle fondamentali della materia. O la materia è solo energia?
Kevin Panko,

Si può evitare qualsiasi mistero del genere costruendo la propria CPU da transistor e chip logici: D (Una delle mie fantasie tecnologiche preferite!) Comunque +1 per una risposta eccezionale.
DarenW,

Punto valido! Anche se l'ultima volta che ho effettivamente utilizzato l'hyperthreading dell'assemblatore è stato probabilmente più comunemente usato come riferimento alla cucitura veloce, piuttosto che alle CPU ...
Dan O

2

C'è qualche buona ragione per imparare / esercitarsi nella programmazione di basso livello. Mi sono dato varie risposte a seconda del contesto.

In primo luogo, sto insegnando la programmazione in C (ma anche OCaml e Java), motivare gli studenti a imparare la programmazione dal lato difficile è probabilmente la parte più difficile del compito. L'argomento migliore che ho trovato finora è la "comprensione": le lingue di livello superiore nascondono molti meccanismi sottostanti e alcune volte non per sempre, ti spingono anche a rimanere al livello superiore anche quando alcuni trucchi di basso livello potrebbero davvero essere utili ( per prestazioni, il più delle volte.) Capire cosa stai usando può davvero aiutarti a usarlo meglio. La mia esperienza di insegnamento mi dimostra che gli studenti che hanno imparato la programmazione di livello inferiore (e altri non orientati all'utente, tali compilatori) sono più adattabili e apprendono più rapidamente nuovi concetti o strumenti di livello superiore.

In secondo luogo, come dici, le prestazioni fanno parte dell'esperienza dell'utente. Il più delle volte, le prestazioni sono viste come una questione di scrittura complessa e vicina al codice macchina. Questo non è sempre il caso, le prestazioni sono molto più una questione di algoritmi e strutture di dati, ma anche di interazione tra algo e dati. Uso un progetto speciale sull'argomento, fondamentalmente è una semplice ricerca di percorsi, ma il vero problema è la dimensione dei dati: il grafico è infinito. L'unico modo per ottenere prestazioni di discesa e adattarsi alla memoria è scrivere un allocatore di memoria dedicato (in effetti due, un allocatore di pool e un allocatore di riciclaggio). Questo è qualcosa che non si può fare nella maggior parte dei linguaggi di livello superiore. In effetti, la maggior parte delle lingue raccolte con immondizia avrà problemi di prestazioni e memoria.

Probabilmente ci sono molti più argomenti come la stabilità (nel senso della storia e la longevità) delle lingue di livello inferiore rispetto a quelle "hype" (il fatto che un linguaggio considerato come riferimento futuro per la programmazione possa scomparire in pochi anni è lungo storia, non si può prevedere la longevità di una nuova roba, ma questo argomento rimane vero per le lingue più vecchie ...), ovviamente c'è anche una questione di gusti, o il fatto che ciò che si può fare nella maggior parte delle lingue di alto livello può anche essere fatto in linguaggi di livello inferiore ma non viceversa (ma considerato ciò, dovremmo tutti codificare solo in assembly ...)

Sono io stesso una trappola in entrambi il mondo (in modo abbastanza diverso), trascorro diversi anni lavorando sul concetto di programmazione teorica, sulla progettazione e la dimostrazione di sistemi di tipo e, facendo ciò, utilizzo e studio solo linguaggi di livello molto elevato (principalmente funzionale, ma anche puro orientato agli oggetti). Recentemente torno dall'altra parte (principalmente programmazione di sistema e kernel) e mi sono trovato abbastanza a mio agio in quest'area mi sto divertendo molto! Per me, il passo successivo è trovare il punto comune: funzionalità linguistiche di livello superiore per la programmazione di livello inferiore! Quindi, finora non esiste un linguaggio per questo (forse google's go for userland programmation system) e sto prendendo in considerazione l'idea di costruire la mia lingua, ma questa è un'altra storia.


1

Direi che non ci sono molte ragioni nel tuo dominio, tuttavia se tu dovessi fare un calcolo ad alte prestazioni (ad es. Gioco, scienza, ecc.) Sarebbe giustificato.


1
Non sono così sicuro che siano rimaste molte aree ad alte prestazioni. Il gioco certamente non richiede lingue di basso livello. Per i giochi, di solito usi i motori o almeno inizi con OpenGL o qualcosa del genere. E per la scienza la parallelizzazione è molto importante e la correttezza. Suppongo che staresti meglio con OCaml o qualcosa del genere. Le aree critiche per le prestazioni non sono più quelle che scricchiolano molti numeri, ma che vengono utilizzate molto frequentemente, come kernel, driver, motori di archiviazione e simili. Immagino che meno dell'1% di tutti gli sviluppatori li abbia mai toccati.
back2dos,

4
@ back2dos, i motori di gioco non appaiono dal nulla: qualcuno deve scriverli. E in cosa pensi sia scritto OpenGL? Non C #. Non è necessario utilizzare lingue di basso livello per la maggior parte delle applicazioni al giorno d'oggi ... ma molte persone lavorano nelle altre aree che lo richiedono.
GrandmasterB,

1

Penso che al giorno d'oggi la programmazione di basso e alto livello possa essere abbastanza separata. Fondamentalmente questo significa che potresti vivere tutta la tua vita professionale senza conoscere C e assemblatore senza problemi. Detto questo, il linguaggio di programmazione C non può insegnarti molto dal punto di vista della programmazione e della progettazione.

Solo per curiosità puoi imparare come funzionano le cose a un livello inferiore. Quando ero all'università, ad esempio, mi piaceva usare gcc per generare codice assembler dal C ++. È stato utile comprendere come sono implementati il ​​polimorfismo e l'eccezione. Ma a parte questo le uniche cose che potresti imparare da C al giorno d'oggi sono:

1) trucchi di memoria sporchi. C è il modo migliore per capire che nella follia dei programmatori non esiste un bottom down :)

2) I GOTO sono effettivamente utilizzati (e utili) per errori di rollback

3) Scopri meglio come funziona l'allocazione di memoria (differenza tra heap e stack chiunque?).

Quindi sostanzialmente la mia tesi è: se hai già finito l'università e non hai ancora bisogno della C, allora non impararla :)


2
Conoscere C per sapere come funzionano le cose a basso livello può aiutare a capire perché le cose vanno male quando si ha un'astrazione che perde.
Michael Shaw,

1

Non è necessario comprendere le lingue di basso livello, ma è necessario comprendere cosa sta succedendo sotto le copertine della lingua di alto livello scelta. L'uso di una lingua di basso livello ti insegnerà questo, ma non è l'unico modo.

Ecco alcuni esempi di concetti di basso livello che possono avere un impatto sulle lingue di alto livello.

puntatori:

List<object> listOne = new List<object>();
List<object> listTwo = listOne;

listTwo.Add(new object());

Debug.WriteLine(listOne.Count); //do you know what this will be?

Stringhe:

string initial = "initial";
string another = initial;

another = "changed!";
Debug.WriteLine(initial); //what about this?

liste:

Quando usi una lista contro una lista collegata? (Quasi impossibile saperlo senza capire a un livello piuttosto basso di come funziona un elenco)

-

È necessario conoscere tutte queste cose? No, ma può avere un impatto e se vuoi essere un maestro di un linguaggio di alto livello devi avere una buona idea del funzionamento interno.


1

Cosa potrebbe insegnarmi la programmazione di basso livello, quali altre lingue non mi insegnerebbero?

In particolare ti insegnerà come funzionano effettivamente i computer. Non c'è altro modo di imparare questo se non attraverso la programmazione di basso livello. Indipendentemente dal tipo di applicazioni che programmi, questo sarà sempre di aiuto. Capirai davvero cosa sta succedendo in profondità sotto tutta quella roba web. E se lavori con Windows, l'intera API è scritta in C, quindi sapendo che la lingua ti consentirà di comunicare direttamente con il sistema operativo, ogni volta che devi utilizzare una funzionalità che manca nelle tue lingue correnti e nelle loro librerie.

Naturalmente la programmazione di basso livello ti consentirà di lavorare con cose completamente diverse, come la programmazione integrata e la programmazione in tempo reale in cui asm / C / C ++ è un must. Se non hai interesse per questo tipo di applicazioni, non c'è davvero molto bisogno di imparare asm / C / C ++.

Inoltre, imparerai bit e byte. Manipolazioni di bit, esadecimali ecc. Queste cose che potresti incontrare di tanto in tanto anche durante la programmazione web / desktop. Gli algoritmi di crittografia sono uno di questi esempi in cui vengono utilizzati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.