La creazione di nuovi software è generalmente una parte importante della maggior parte dei lavori di programmazione? [chiuso]


63

Lavoro nello sviluppo di software da oltre 10 anni e mi rendo conto che raramente riesco a creare qualcosa di "nuovo". Mi rendo conto che "nuovo" è un termine vago, ma lo definirei come qualsiasi cosa, da un ovvio nuovo progetto su larga scala a una nuova funzionalità di grandi dimensioni in un progetto esistente (dire qualcosa che richiederebbe un pensiero nel suo design e che potrebbe impiegare 2 settimane o più per completare). Forse una linea guida approssimativa è qualcosa di nuovo se richiede una specifica scritta. Penso che la maggior parte dei programmatori sappia di cosa sto parlando: sei nella zona, scrivendo un sacco di codice ad un ritmo veloce.

Comunque, ripensando a quello che ho fatto, stimerei che meno del 10% del mio tempo è dedicato a "nuovi" lavori. Ci sono cose come "adattare questo sistema esistente per funzionare in questo nuovo ambiente", che richiede certamente molta pianificazione, ma la codifica effettiva e le "nuove cose" si riducono a piccoli cambiamenti in molti punti del codice. Allo stesso modo per le richieste di funzionalità di piccole dimensioni - se so cosa fare, queste possono spesso essere finite in meno di un'ora, e se non lo faccio, è solo un sacco di leggere il codice e capire cosa fare (il che mi frustra perché imparo molto meglio facendo, non leggendo).

In generale, mi sento come se non stessi creando nulla per la maggior parte del tempo. Ho ipotizzato che questo fosse il caso nella maggior parte dei luoghi: un nuovo prodotto sarebbe uscito piuttosto rapidamente e a quel punto tutti sarebbero stati entusiasti e cancellando il codice a un ritmo veloce, ma poi una volta in diretta si passa alla modalità di manutenzione, dove alcune delle successive modifiche sarebbero considerate "nuove e creative".

Ho sbagliato? Sto descrivendo accuratamente la maggior parte dei lavori di programmazione o la maggior parte dei programmatori ha la sensazione di creare spesso cose nuove?


11
@JamieTaylor Tradotta nei termini metaforici, la domanda è: è tipico correggere sempre il modello Lego di qualcun altro e crearne uno raramente?
Caleb,

22
@Joe, hah! Quindi tu sei il ragazzo che produce tutti quei sistemi legacy * # @ * e!% Che dobbiamo mantenere per sempre ?! ;-P
Péter Török,

14
@Joe, sì, grazie mille. Forse se potessi scrivere solo un po 'più di unit test, sarei completamente contento :-)
Péter Török

8
@Joe, che mi fa venire in mente il vecchio adagio, che non ho trovato particolarmente adatto, cioè fino ad ora: "codifica sempre come se il prossimo che assumesse il tuo codice fosse un pericoloso psicopatico che sapeva dove vivi"; -)
Péter Török

11
@JonMcdonald Non dovrebbe essere deprimente: nessun lavoro è tutto rose e la manutenzione di una base di codice esistente è probabilmente il modo più veloce per acquisire esperienza e migliorare le tue capacità di ingegnere. Trascorrere del tempo in manutenzione ti aiuterà a capire ed evitare tutti gli errori tipici che portano in primo luogo a un codice non mantenibile e ti aiuterà ad apprezzare cose che altrimenti non ti interesserebbero, come l'analisi del codice statico e la creazione di test automatici delle unità.
Ben Cottrell,

Risposte:


66

Una grande quantità di lavoro software è la manutenzione. Nessun responsabile delle assunzioni te lo dirà, ovviamente, ma è certamente il caso.


13
Questo è probabilmente vero, ma la manutenzione è ancora molto importante, e talvolta può anche essere intellettualmente impegnativa :)
joshin4colours

3
Non c'è assolutamente nulla di sbagliato nella manutenzione. Ma la gente lo trova meno affascinante, quindi le descrizioni dei lavori tendono a minimizzarlo.
Scott C Wilson,

Per manutenzione intendi far sì che il software funzioni come richiesto dalle specifiche in continua evoluzione. La manutenzione come concetto si applica solo all'hardware e ad altre cose che possono rompersi casualmente a causa di fattori fisici. Il software non è gestito, è stato riprogettato e refactored.
Rudolf Olah,

3
@omouse - a volte sì, ma a volte corregge solo bug palesi nell'implementazione per soddisfare le specifiche originali. Ma hai ragione: una serie di attività sono coperte dalla rubrica "manutenzione".
Scott C Wilson,

@Mouse, riprogettazione e refactoring hanno anche significati e non coprono cose che generalmente chiamiamo "manutenzione". Se alcuni software utilizzano una funzione ormai obsoleta o un'API esterna cambia, la cosa che farai non è né riprogettazione né refactoring.
cbrandolino,

59

Sì, la tua percezione è accurata. È una verità assoluta che molto più tempo, denaro e sforzi vengono spesi per mantenere i sistemi piuttosto che per creare nuovi sistemi. Quindi, ovviamente, l'allocazione del tempo della maggior parte dei programmatori lo rifletterà.

Parte della ragione di ciò è che molte persone, quando riescono a fare "nuove e creative", lo fanno male, quindi mantenere il sistema è difficile (questo è particolarmente probabile se non hanno mai fatto manutenzione da soli - nessuno che abbia costantemente lavorato su piccoli progetti greenfield può davvero affermare di essere competente).

Un altro motivo (probabilmente più grande) è che la maggior parte dei sistemi è progettata per essere continuamente utile, non solo per un evento unico. Quindi continuano ad abituarsi per molto più tempo di quanto necessario per svilupparli. Ma durante quel periodo, i requisiti cambiano (e vengono aggiunti) a causa di cambiamenti nella legislazione, nel mercato, nella ricerca, negli utenti, qualunque cosa. E questo significa lavori di manutenzione.


15
+1 per "nessuno che abbia costantemente lavorato su piccoli progetti greenfield può davvero affermare di essere competente"
mattnz,

1
Che cos'è "un piccolo progetto greenfield"?
Biscotti di farina di riso,

@RiceFlourCookies: Greenfield è un termine per un lavoro endevour completamente nuovo. In questo caso, un progetto è iniziato da zero.
Steven Evers,

@RiceFlourCookies e sebbene piccolo sia relativo, i progetti che possono essere realizzati da una persona potrebbero essere ragionevolmente considerati piccoli.
Scott C Wilson,

23

I sistemi legacy sono quelli di successo. Sono sopravvissuti al processo di sviluppo iniziale in cui il 50% dei progetti fallisce (anche dopo che il successo è stato ridefinito!). Sono sopravvissuti a un ambiente aziendale in evoluzione. Probabilmente sono sopravvissuti a una decina di proposte di giovani programmatori ingenui per riscrivere il tutto in Java o qualsiasi cosa fosse di tendenza in quel momento. Sono stati abbastanza fortunati che qualunque reparto, azienda o agenzia che il software stava servendo è sopravvissuto ai vari tagli di budget, riorganizzazioni, fusioni ecc.

Probabilmente meno del 5% del software scritto sarà ancora in esecuzione dieci anni dopo.

Quindi, piuttosto che lamentarti di ciò, vedi come un privilegio lavorare su una storia di successo così darwiniana e un'opportunità per imparare cosa funziona nel mondo reale e perché.


8
... o sono sopravvissuti perché c'era qualcuno con abbastanza influenza decisionale e con un interesse nascosto nel mantenere il mastodontico lascito in carica per 10 o più anni, come assicurarsi il suo lavoro, la pensione o semplicemente essere troppo incompetente e le sue abilità erano troppo superate per trovare un nuovo lavoro
Marek,

@marek può davvero essere entrambi.
nicolas,

8
Il fatto che qualcosa sopravviva non significa che sia ottimale o addirittura buono. Significa solo che è "abbastanza buono" che nessuno lo ha ancora messo fuori dalla sua miseria. La principale forza selettiva in natura è la concorrenza; quando c'è poca concorrenza, puoi ottenere alcuni organismi piuttosto incasinati. La concorrenza funziona anche nel software, ma i sistemi interni di solito non hanno molta concorrenza. Il risultato è che i sistemi interni sono spesso avvitati al massimo.
Caleb,

@Caleb - Come sistema di regola generale in cui gli sviluppatori hanno ascoltato gli utenti e bloccato i requisiti sopravvivono. Non importa quanto sia scritto male! I sistemi in cui gli sviluppatori stanno cercando di abbinare l'ultimo modello di progettazione, implementando le ultime mode e ossessionando il loro rientro, non arrivano alla prima versione. Il codice di lavoro batte sempre abbastanza, codice conforme alle parole d'ordine.
James Anderson,

14

Il termine che viene spesso utilizzato per nuovi progetti che non dipendono dallo sviluppo precedente è progetto greenfield . Occasionalmente potresti vedere il termine nelle liste di lavoro: sapere che puoi iniziare da zero piuttosto che ereditare l'impegno fallito di qualcun altro può rendere un lavoro più attraente.

I progetti software di successo in genere impiegano molto più tempo a essere mantenuti rispetto a quelli realizzati come nuovi progetti, quindi non sorprende affatto che non si riesca a fare un sacco di cose completamente "nuove".

Inoltre, creare qualcosa di completamente nuovo richiede molto lavoro. Anche su un progetto greenfield, probabilmente sceglierai una serie di strumenti per aiutarti: piattaforma, compilatore, framework, librerie, ecc. Non appena fai queste scelte, hai imposto alcuni vincoli al tuo progetto. Questo non vuol dire che non stai più facendo nuovi lavori, solo che "nuovo" è un termine relativo qui. Da lì non è un grande passo vedere l'aggiunta di una funzione o di un modulo a un progetto esistente come "nuovo" anche se non lo si definirebbe un progetto greenfield.


7
"l'impegno fallito di qualcun altro": i sistemi legacy sono le storie di successo di Darwin, i progetti falliti non vengono mantenuti!
James Anderson,

2
@JamesAnderson Punto preso, ma il successo tecnico non è l'unica forza selettiva nell'ecologia del software. Chi non ha visto il cane finito a metà di un progetto che è importante per i manager ma ritenuto troppo lungo per ricominciare?
Caleb,

6

Dipende dal lavoro che cerchi.

Ho lavorato solo una volta per un'azienda di prodotti software puri in cui ho lavorato alla loro singola applicazione placcata oro in una piccola squadra di start-up.

Altrimenti ho lavorato per aziende tecnologiche che avevano bisogno di software per supportare la loro ricerca e sviluppo interna o prodotti esterni.

Il lato positivo è che riesco a creare prodotti completi per la finitura e praticamente quello che voglio. A volte puoi anche provare tecnologie più recenti rispetto a quando sei bloccato aggiungendo funzionalità a un'applicazione leader di mercato esistente.

Il rovescio della medaglia è che sei parte del costo, non parte del prodotto. Quindi ho avuto progetti fissi perché "non stiamo realizzando software" / "il software non è il core business" = è sorprendente il modo in cui le aziende pensano di poter vendere una macchina da $ 100 K senza software per farla funzionare!


Mi stupisce anche il modo in cui le aziende pensano di non aver bisogno di una soluzione personalizzata per il loro problema personalizzato e che un milione di righe di 278 colonne possono essere facilmente e rapidamente manipolate in Excel, anziché in un db.
Spencer Rathbun,

@SpencerRathbun Ciò che mi sorprende ancora di più di questo è quando dai loro una stima per creare il software personalizzato, iniziano immediatamente a metterti in discussione e a chiedere: "Il loro software open source gratuito non può darci gratuitamente funzionalità X personalizzate?"
maple_shaft

7
@maple_shaft la cosa ancora più divertente è quando dicono "possiamo comprare X per $ 10K e questa soluzione per tutti gli usi si adatterà perfettamente al nostro problema personalizzato senza configurazione! BTW ti occuperai di metterlo in funzione e tutti i problemi / i bug con il software che abbiamo acquistato sono colpa tua ".
Spencer Rathbun,

3
@SpencerRathbun Hai vinto, questa è la situazione peggiore in cui trovarsi.
maple_shaft

5

Invece di vedere il codice legacy come ripulire continuamente il disordine di qualcun altro, guardalo come un'opportunità per lavorare su molti nuovi progetti.

Pensaci, ogni nuova funzionalità aggiunta a un sistema è un piccolo progetto al suo interno. È comunque necessario applicare l'intero SDLC per assicurarsi di aver completato correttamente il lavoro. Certo, probabilmente ti viene data una specifica per la funzione, ma di solito i dettagli sono stati lasciati in sospeso, quindi spetta a te analizzare il problema come mostrato, progettare il metodo migliore per applicare la modifica, testarlo, codificarlo, e quindi rilasciarlo di nuovo sul sistema di controllo della versione, e molto probabilmente mantenerlo in futuro.

È stata la mia esperienza che spesso non riesci a lavorare in un campo completamente verde, e spesso quando hai avuto la fortuna di farlo, dovrai aspettarti di vedere il progetto attraverso una buona parte della sua manutenzione e forse anche per la durata del prodotto o per l'intero periodo in cui ti trovi con un determinato datore di lavoro. Questo perché la tua esperienza intima con un prodotto significa che diventi un repository di conoscenze e può essere considerato costoso trasferirti ad altre cose. Quando si avvia un prodotto esistente, è perché il datore di lavoro ha recentemente perso una risorsa o ha bisogno di più risorse sul progetto e le aziende devono assicurarsi che non subisca una perdita eccessiva sull'investimento effettuato nel suo software . Questa è la realtà di essere un ingegnere del software.

Ho lavorato in IT per quasi 22 anni con gli ultimi 15 come sviluppatore di software, e in tutto quel tempo ho creato solo circa 5 nuovi prodotti, con la maggior parte del mio tempo o mantenendo quei prodotti a lungo termine o mantenendo qualcun altro Prodotto. Ciascuno mi ha dato sfide e problemi da risolvere, e ognuno è stato trattato non semplicemente come un grande progetto di cui faccio parte, ma anche come una serie ENORME di microprogetti da completare.

È incredibile come un po 'di calisthenics mentale possa cambiare totalmente la tua percezione e il godimento del lavoro quotidiano che fai. ;-)


4

Penso che molti lavori di sviluppo software comportino il miglioramento di un prodotto esistente o l'adattamento del codice esistente a un nuovo cliente o mercato.

Non si tratta davvero di "manutenzione". Ad esempio, VMWare ha appena rilasciato la versione 8, è un importante aggiornamento del loro prodotto principale. Sospetto che pochi degli sviluppatori che hanno fatto questo lavoro fossero lì quando è stata scritta la prima riga di codice per VMWare. Hanno costruito il loro importante aggiornamento sul codice scritto da ragazzi che da tempo sono passati.

Nella beta di Workplace c'è una domanda su come funziona il sistema di progetto personale al 20% di Google .

Sono sicuro che Google ha capito che i migliori sviluppatori vogliono essere presenti alla creazione di nuovi prodotti software e alla fine si stancheranno di anni di aggiunta di piccole funzionalità e di modifica delle gui per il prossimo rilascio.

Avendo il 20% di progetti, suppongo che lo sviluppatore di Google non dispiacerà rimanere per migliorare i progetti di Google dal momento che lui o lei può ancora divertirsi di essere lì all'inizio di qualcosa di nuovo.


2

Trascorrerai il tuo tempo a creare nuove funzionalità e a modificare le funzionalità del codice esistente per adeguarti alle nuove specifiche.

Altri lo chiamano manutenzione, ma è un termine orribile. È una riprogettazione e un refactoring o ricodifica del software per renderlo conforme a una nuova idea di cosa dovrebbe fare il programma.


2

Direi che dipende dalla compagnia per cui lavori.

Il mio primo lavoro è stato una società di software di contabilità il cui prodotto principale era un sistema ERP, in competizione allo stesso livello di Great Plains o Peachtree (come in te ci sei passato da QuickBooks o lateralmente quando ti sei stancato dello schema offuscato del GP o di qualsiasi altra cosa hai pensato che fosse sbagliato con PT, poi ti sei spostato completamente fuori dal livello in un pacchetto come SAP). Quel lavoro consisteva nella manutenzione del 99,99%, definito come correzione di bug e aggiunta di "piccole cose", senza cambiare sostanzialmente il modo in cui il software funzionava o cosa poteva fare. Ho lasciato l'azienda quando il CEO voleva fare una riscrittura di una pagina del sistema, il che sarebbe stato bello se non avesse insistito su diverse funzionalità di design che sono chiaramente anti-pattern, come la piattaforma interna (che consente un alto grado di personalizzazione del programma fornendo sostanzialmente al cliente un VS Designer stupido,

Il mio lavoro successivo fu una ditta a contratto che si occupava di "sviluppo chiavi in ​​mano"; il sistema specificato dal cliente è stato realizzato da zero, hardware e software, quindi al completamento del progetto è stato consegnato al cliente che poteva mantenerlo da solo o mantenere i servizi dell'azienda a un canone mensile. Il mio lavoro consisteva nello sviluppo di uno di questi grandi progetti, e quindi mentre lavoravo lì praticamente tutto ciò che avevo fatto non esisteva prima di iniziare. Anche allora, lo sviluppo è intrinsecamente iterativo; stai sempre aggiungendo ciò che hai già (anche se ciò che hai non è niente) e devi evitare e correggere i problemi di regressione (nuove cose che rompono quelle vecchie). E una volta che il progetto è passato allo stato di "garanzia",

Il mio attuale lavoro è tornato allo sviluppo interno, per un'azienda di sicurezza che utilizza il monitoraggio video e il feedback audio per fornire la verifica del segnale di allarme e altri servizi di "guardia virtuale". Questo campo sta crescendo rapidamente e si sta ancora sviluppando; nuove attrezzature entrano continuamente sul mercato, vengono registrati nuovi clienti che vogliono che facciamo nuove cose e i prodotti esistenti non soddisfano più l'adattamento delle normative UL e governative. Il 99% di questo lavoro è "integrazione"; scrivere nuovi software che non sono mai esistiti prima, per far funzionare un nuovo equipaggiamento o software nuovo ma preesistente con un altro equipaggiamento o software probabilmente più vecchio preesistente, in modo che possiamo fare cose nuove con entrambi.


1

Direi che dipende molto dalla natura del tuo ruolo.

Faccio parte di una piccola squadra e, come tale, devo mantenere e supportare tutto ciò che creo.

5 anni fa la maggior parte di ciò che facevo era "nuovo" - ora direi che la manutenzione del codice esistente occupa almeno la metà del mio tempo, con un ulteriore 25% di "nuove" versioni di sistemi esistenti.

Ma se lavorassi esclusivamente come sviluppatore con un team per occuparti della manutenzione e del supporto dopo aver rilasciato il codice, tecnicamente tutto sarebbe "nuovo". Se riesci a trovare un lavoro in cui non è richiesto il mantenimento del tuo codice, accettalo!


1
  1. Dipende da quanto è pericolosa la tua posizione lavorativa: ;-)

    Se lavori per una nuova società che sviluppa nuovi prodotti con un alto rischio che la società sopravviva, probabilmente crei alcuni nuovi fantastici prodotti.

    Se lavori per una vecchia azienda che ha una posizione stabile sul mercato, è più probabile che codifichi in modalità manutenzione ;-).

  2. La creazione di nuovo software è sempre molto allettante . La verità è difficile farlo nel modo giusto . Fare codice gestibile non è un compito banale.

    Se pensate a questi innumerevoli aspetti, dovete assicurarvi di scrivere un buon codice: registrazione adeguata, monitoraggio adeguato e acquisizione di statistiche, progettazione descrittiva efficiente e che aiuti anche le persone non familiari a partecipare al vostro progetto, documentazione, test automatici e sviluppi guidati dai test.

Non molte persone lo stanno facendo bene, quindi dobbiamo mantenere il loro codice e lucidarlo allo stato corretto. ;-)

La buona notizia è che se sei in azienda abbastanza a lungo, puoi influenzare il modo in cui è scritto il nuovo codice :-)


1

La manutenzione o meno è principalmente sotto il tuo controllo. Nel mio caso, la maggior parte del mio lavoro negli ultimi 15 anni è stato un nuovo sviluppo. Questo perché cerco lavoro che mi permetta di fare un nuovo sviluppo. Non sono un appaltatore e in genere non faccio sviluppo web. Ho quasi sempre lavorato per piccoli datori di lavoro e di solito lavoro in aree di nicchia (sviluppo di GUI desktop, strumenti di controllo qualità, strumenti di sviluppo, mercati verticali).

Ho anche visto e sperimentato in prima persona che i migliori programmatori di una squadra in genere (anche se non sempre) ottengono i lavori migliori. Quindi, concentrati sull'essere il miglior programmatore della tua azienda e inizierai a vedere i nuovi sviluppi venire sulla tua strada.


1

Lo sviluppo della manutenzione è un compito difficile, per molti aspetti più difficile del nuovo sviluppo. Nella mia esperienza, i datori di lavoro amano mantenere uno sviluppatore che fa manutenzione, specialmente se sono bravi a farlo. Trovare buoni sviluppatori di manutenzione nelle tecnologie legacy è più difficile che trovare qualcuno in grado di lavorare con le ultime tecnologie.

Ho lavorato in un'azienda che era divisa in un team di prodotto, che era tutto per la manutenzione, e un team di progetto, che era tutto nuovo sviluppo. C'erano grandi sviluppatori da entrambe le parti, ma i manutentori erano decisamente più specializzati e usavano la tecnologia legacy.

Potrei suggerire di tornare indietro e chiedere un nuovo lavoro di sviluppo? E se il tuo datore di lavoro esegue solo la manutenzione, allora forse devi andare avanti?


0

Direi che dipende da molti fattori. Dove lavori, che tipo di prodotti realizzi, come è organizzata la tua squadra, ecc.

Nei quattro anni in cui ho lavorato nella mia azienda, direi che il 70-80% del mio tempo è dedicato alla creazione di qualcosa di nuovo. Probabilmente il 50-60% di questo viene speso per progetti di grandi dimensioni che rappresentano un codice completamente nuovo, mentre il resto del tempo viene impiegato per migliorare le funzionalità attuali.

Parte di ciò che so è come funziona la mia azienda. Non tutti nel mio team di sviluppo trascorrono così tanto tempo a sviluppare nuove funzionalità. Ci sono un numero che concentra il loro tempo in nient'altro che nella risoluzione di bug / caccia. Se si tratta di una funzionalità nuova di zecca o hanno bisogno di aiuto, allora viene preso a calci da me per indagare. In generale, tuttavia, quella piccola squadra di cacciatori di bug è ciò che consente al gruppo più ampio di sviluppatori di proseguire senza interruzioni.


0

Lavoro da quasi tre anni come unico sviluppatore in un'azienda che ha utilizzato QuickBooks ed Excel e nient'altro quando ho iniziato. Ora abbiamo un'applicazione Windows Form , un'installazione di SharePoint , SQL Server + Reports, un componente aggiuntivo di Excel e un componente aggiuntivo di Outlook.

Proprio oggi , ho installato per la prima volta un sistema di biglietteria perché ho perso la capacità di gestire le richieste e-mail a una velocità che ha impedito agli utenti di lamentarsi, quindi vedo che questo è un segno che ho inserito la modalità di manutenzione.

I miei precedenti lavori sono stati più simili a quelli che gli altri hanno pubblicato, ma ho pensato che avrei gettato la mia esperienza atipica solo perché dimostra che non saprai mai quale sarà il prossimo lavoro. Sono sfinito, ma la quantità che ho imparato in questo lavoro è valsa la pena.


La modalità di manutenzione è avvenuta molto tempo fa ... Proprio ora hai bisogno di strumenti per aiutarti.

sono contento di non provare sentimenti perché potrebbero essere feriti dalla sola risposta su questa discussione ad avere punti negativi :(
Aaron Anodide

Bene, non rispondi alla domanda posta.

0

Alcune organizzazioni più grandi come la società per cui lavoro hanno una politica di disattivazione del software dopo un certo numero di anni, forse perché il linguaggio di sviluppo in cui è stato scritto non viene più utilizzato (Delphi anyone?) O la piattaforma viene sostituita (Windows XP) o requisiti normativi lo richiedono. Ad esempio, i programmi a due livelli che parlano direttamente con un database vengono ora disattivati ​​a favore di tre livelli che utilizzano connessioni Kerberized per una maggiore sicurezza.

Gli utenti hanno ancora bisogno di quella funzionalità originale, quindi viene sviluppata una versione completamente nuova che utilizza le attuali tecniche all'avanguardia.

Aspettati un ciclo di sostituzione di 5-7 anni per questo tipo di cose. Ad esempio, entro il 2020, mi aspetto che il software WPF (client) / Java (server) che sto scrivendo sarà una tecnologia obsoleta e verrà sostituito da qualcosa di più nuovo.

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.