it-swarm.it

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

Per anni ho considerato di scavare in quelle che considero lingue "di basso livello". Per me questo significa C e Assembly. 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 potrebbero 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

  • Good design: funzionalità ben concepite accessibili attraverso un'interfaccia utente ben ponderata.
  • Correctness: 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 ragionevolmente velocemente (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 Assembly 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 so, scrivere Assembly in questi giorni per i processori in uso nelle attuali CPU non è solo inutilmente complicato, ma rischia di provocare 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 guardando i dump principali: D
Attualmente sto sperimentando lingue e interpreti, quindi se c'è qualcosa che vorrei pubblicare, suppongo che porterei un concetto funzionante su C, anche se C++ potrebbe fare altrettanto.
Ancora una volta, grazie a tutti per le risposte e la comprensione.

32
back2dos

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 RAM! http://users.ox.ac.uk/~uzdm0006/scans/1kchess/

9
user1249

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 nei linguaggi astratti, 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 come 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.

29
Jonathon

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 e algoritmi di dati 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 memoria (larghezza di banda), dalla cache della CPU alla latenza della rete transoceanica. Ciò aiuterà le tue capacità di sviluppo delle applicazioni a tutti i livelli.
    • Ancora più importante, è bene conoscere gli scenari in cui a piccolo il riarrangiamento poco appariscente del codice di alto livello può comportare un drammatico miglioramento della velocità.
      • A volte il motivo può essere compreso solo nell'implementazione di basso livello nel contesto della gerarchia di memoria.
      • Non capire la causa naturale di questa possibilità porta a ignoranza , paura , e infine a 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.
  • Apprezzo 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, apprezza che i componenti di basso livello sono quasi sempre più complicati nelle loro implementazioni , tutt'altro che immaginabile 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.
15
rwong

se vuoi capire come funziona machine, 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 - allora non preoccuparti.

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

8
Steven A. Lowe

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 avevano semplicemente molto più senso. Non avevo mai usato ripiegare uno dei miei codici prima, ma dopo l'hashell lo vedo praticamente ovunque vedo gli array, quindi è molto probabile che se impari un po 'di C diventerai molto più consapevole delle caratteristiche relative alle prestazioni dei vari costrutti nella tua lingua preferita. Qualche minuto fa stavo ascoltando un discorso sulla scrittura veloce e ottimizzata di javascript e l'oratore ha detto "Se è difficile farlo in C, allora sarà molto lento in javascript." Il suo intento è che javascript sia un linguaggio interpretato e l'interprete è scritto in C o C++. Questo mi è passato per la testa perché ho poca esperienza in C e non ho idea di cosa sia difficile o facile in C.

8
davidk01

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 quanto più veloce può diventare un programma quando scritto in C invece di, diciamo, Java. Potresti anche imparare ad apprezzare davvero le funzionalità di linguaggi di livello superiore, come la garbage collection.

7
user281377

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 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.

5
DarenW

In una parola, divertente. Quando giocavo con l'assemblatore (avendo lavorato da VB a C++, C ecc.) È stato semplicemente fantastico spostare i dati da una parte del processore a un'altra. sensazione di sapere esattamente cosa stava succedendo all'interno della CPU, senza preoccupazioni per quello che stava succedendo al di sotto di cui non si era a conoscenza. Inoltre una grande sensazione 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
Dan O

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

Innanzitutto, 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 compilatori non orientati all'utente) 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 lingue di livello inferiore, ma non viceversa (ma considerato ciò, dovremmo codificare tutti solo in Assembly ...)

Sono io stesso una trappola in entrambi il mondo (in modo abbastanza diverso), trascorro diversi anni a lavorare 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 uno funzionale, ma anche puro orientato agli oggetti.) Di recente 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.

2
Marwan Burelle

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
Darknight

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 :)

1
Emiliano

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 dei meccanismi interni.

1
Alistair

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 a 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.

1
user29079