giovedì 26 giugno 2014

Energized Work by James Shore

Energized Work

Pubblico
Allenatori
Tutta la squadra
Noi lavoriamo a un ritmo che ci permette di fare il nostro lavoro migliore, più produttivo a tempo indeterminato.
Mi piace la programmazione. Mi piace risolvere i problemi, scrivere buon codice, a guardare i test che passano, e in particolare la rimozione di codice inutile mentre faccio "refactoring". Programmo nel mio tempo libero e talvolta anche pensare al lavoro sotto la doccia.
In altre parole, io amo il mio lavoro. Eppure mi ha messo su una squadra con obiettivi poco chiari, poca responsabilità collettiva, sostenendo, e lotte di pancia, e mi sveglio temendo di andare al lavoro. Passo le mie ore in ufficio, ma sarò tentato di spendere le mie mattinate a leggere e-mail e miei pomeriggi a studiare buon codice durante la navigazione attraverso i siti web tecnici marginalmente correlati.
Siamo stati tutti in questa situazione. Perché siamo professionisti, ci sforziamo di produrre un lavoro di qualità anche quando ci sentiamo demoralizzati. Consideriamo, però, i momenti di maggiore produttività nella vostra carriera. Hai notato una grande differenza quando ti svegli e senti benedetto per andare al lavoro? Non è molto più soddisfacente quando si lascia il lavoro a fine giornata, sapendo che avete compiuto qualcosa di solido e utile?
La pratica di XP di Energized Work riconosce che, sebbene i professionisti possono fare un buon lavoro in circostanze difficili, fanno del loro meglio, il lavoro più produttivo avviene quando sono pieno di energie e motivato.

Come essere Energized

Vai a casa in tempo.
Uno dei modi più semplici per essere alimentato è quello di prendersi cura di se stessi. Vai a casa in tempo ogni giorno.Trascorri del tempo con la famiglia e gli amici e impegnati in attività che richiedono la vostra mente fuori di lavoro. Mangia cibi sani, esercizio fisico, e ottieni l'abbondanza del sonno. Mentre sei impegnato con queste altre cose, il cervello si accende sugli eventi della giornata. Spesso avrete nuove intuizioni di mattina.
Se il tempo di qualità è lo yin dell' Energized Work, rimanere concentrato a lavoro è il yang. Durante il lavoro, dare la massima attenzione. Spegnere interruzioni come la posta elettronica e messaggistica istantanea ( skype, etc...) . Tacere i vostri telefonini. Chiedete al vostro project manager di difenderti dagli incontri inutili e di politica organizzativa.
Quando lo yin e lo yang incastrano perfettamente, ti svegli la mattina, ben riposati e desiderosi di iniziare la giornata. Alla fine della giornata, sarete stanchi, ma non esausti, e soddisfatti del lavoro che avete fatto.
Questo non è facile. Energized Work richiede un sostegno ai luoghi lavorativi e alla vita domestica. E', comunque, una scelta personale; non c'è alcun modo per obbligare qualcuno a essere Energized. Tuttavia, è possibile rimuovere gli ostacoli.

Sostenere Energized Work

Stare a casa quando si è malati. Per Il rischio di infettare troppe altre persone.
Una delle mie tecniche preferite come coach è quello di ricordare a tutti di tornare a casa in tempo. Gente stanca commette errori e prende scorciatoie. Gli errori risultanti possono finire per costare più di quanto vale il lavoro speso. Questo è particolarmente vero quando qualcuno è malato; oltre a fare un lavoro scarso, avrebbe potuto infettare altre persone.
Alleato
Pair programming
Pair programming è un altro modo per incoraggiare l'Energized Work. Essa incoraggia l'attenzione come nessun altra pratica. Dopo una giornata piena di pair programming, sarete stanchi ma soddisfatti. E' particolarmente utile quando non sei al tuo meglio: l'abbinamento con qualcuno sicuramente può aiutare a rimanere concentrati.
Può sembrare sciocco, ma avere cibo sano a disposizione sul posto di lavoro è un altro buon modo per sostenere l'Energized Work. La colazione è davvero il pasto più importante della giornata. Gli abbassamenti di metà pomeriggio sono anche comuni. Cereali, latte, verdure, ed energia spuntini sono una buona scelta. Snack e cibo spazzatura, anche se popolari, contribuiscono al crollo di metà pomeriggio.
Alleato
Visione
La natura del lavoro fa anche la differenza. [McConnell 1996] riporta che gli sviluppatori di software sono motivati ​​a fare bene, il lavoro intellettualmente stimolante. Non tutti i progetti saranno in grado di nutrire i poveri o risolvere problemi completamente, ma una chiara affermazione convincente del perché il prodotto è importante può avere un lungo cammino. Creare e comunicare questa visione è la responsabilità del manager di prodotto.
Alleato
Il Gioco di pianificazione

Un obiettivo raggiungibile va di pari passo con una visione convincente. Nulla distrugge il morale più velocemente di essere ritenuti responsabili per un obiettivo irraggiungibile. Il gioco pianificazione risolve questo problema unendo valore per il cliente con le stime degli sviluppatori di creare piani realizzabili.

Parlando di piani, ogni organizzazione ha una certa quantità di politiche. A volte, le politiche portano alla trattativa sana e compromettente. Altre volte, portano a richieste irragionevoli ed al cercare colpevoli. Il project manager dovrebbe occuparsi di queste politiche, lasciando che la squadra sappia cosa è importante e proteggendoli da ciò che non lo è.
Alleati
Workspace Informativa
Segnalazione

Il project manager può anche aiutare i membri del team nel soddisfare il lavoro spingendo indietro le riunioni inutili e le chiamate in conferenza. Fornire uno spazio di lavoro informativo e di reporting appropriato può eliminare la necessità di riunioni. In un ambiente con un sacco di distrazioni esterne, vengono spesso rese inutili ore centrali di sviluppo ogni giorno, sarebbe necessario isolare almeno una o due ore di inizio giornata. Durante il quale tutti sono d'accordo di non interrompere la squadra.
Infine, le squadre "inquadrate" hanno un sacco di energia. Sono molto soddisfatte, anche. È possibile riconoscere una squadra "inquadrata" da quanto i suoi membri amano trascorrere del tempo insieme. Vanno a pranzo insieme, condividono barzellette, e possono anche socializzare al di fuori del lavoro. Come Energized Work, non è possibile forzare l' "inquadrameto", ma si può incoraggiarla; molte delle pratiche di XP farlo. Il classico lavoro su questo argomento, [DeMarco e Lister 1999] 's Peopleware , vale la pena di leggerlo.

Prendere Pause

Fermarsi quando si sta facendo più errori del progresso.
Quando stai facendo più errori che progressi, è il momento di prendersi una pausa. Se siete come me, però, quello è il momento più difficile in cui fermarsi. Mi sento come se la soluzione fosse proprio dietro l'angolo, anche se è stata proprio dietro l'angolo per gli ultimi 45 minuti, e io non voglio smettere finché non la trovo. Ecco perché è utile per qualcun altro mi ricordi di smettere. Dopo una pausa o una buona dormita la notte, io di solito vedo il mio errore subito.
A volte uno spuntino o passeggiata intorno all'edificio è abbastanza buono. Per i programmatori, commutare le coppie può aiutare. Se è già la fine della giornata, però, andare casa è una buona idea.
Di solito è possibile dire quando qualcuno ha bisogno di una pausa. Arrabbiarsi, imprecando al computer, e bruschi movimenti sono tutti segni. In un ambiente altamente collaborativo, oscurarsi -non parlando- può anche essere un segno che qualcuno ha bisogno di una pausa. Quando ho noto un paio di programmatori che sussurrano gli uni agli altri, mi chiedo quanto tempo è passato dal loro ultimo passaggio dei test. Spesso ricevo una risposta imbarazzata, e ciò quando ricordo loro di prendere una pausa.
Suggerire una pausa richiede una certa quantità di delicatezza. Se qualcuno ti rispetta come un leader, allora dovresti essere in grado di dirgli semplicemente di smettere di lavorare. In caso contrario, lo allontanarsi dal problema per un minuto in modo che possa schiarirsi le idee. Provare a chiedergli di aiutarvi per un momento, o per fare una breve passeggiata con voi per discutere qualche problema che stai affrontando.

Domande

Cosa succede se non sono pronto a testare il mio codice ed è tempo di tornare a casa?

Alleati
Test-Driven Development
Continuous Integration
Se stai praticando sviluppo test-driven e continuos integration, il codice dovrebbe essere pronto per il check-in ogni pochi minuti. Se siete alle prese con un problema e non è possibile il check-in, andate a casa comunque. Spesso la risposta sarà evidente al mattino.
Alcune squadre revertano (cancellano) il codice che non passa tutti i test alla fine della giornata. Questa suona dura, ma è una buona idea: se non si può fare facilmente check-in, siete andati fuori pista. Potrai fare meglio il lavoro al mattino. Se stai praticando bene continuos integration, la perdita del codice sarà il minimo e avrai ancora imparato dall'esperienza.

Io lavoro in una startup e 40 ore solo non sono sufficienti. Posso lavorare di più?

Se avete paura di andare a lavorare la mattina, non si è eccitato.
Un ambiente di startup ha spesso un sacco di emozioni e di cameratismo. Questo porta ad avere più energia e potrebbe significare che si può lavorare per molto tempo e dedicare ancora molta attenzione. D'altra parte,le start-up a volte confondono lunghe ore di lavoro con dedizione alla causa. Fare attenzione a non lasciare che la dedizione ignori il vostro buon giudizio in merito a quando si è troppo stanchi per fornire contributi utili.

Abbiamo una scadenza importante e non c'è modo di farlo senza tenere la testa bassa e spingere oltre. Abbiamo messo da parte Energized Work per ora?

Uno sprint verso il traguardo potrebbe aumentare la vostra energia. Non c'è niente come un Code Party a tarda notte, quando la squadra porta in pizza, ognuno lavora sodo, tutti i cilindri scottano, e il lavoro arriva tutto insieme all'ultimo momento. Un grande sprint può aiutare la quadratura del team, dando il senso di realizzare qualcosa di importante di fronte alle avversità. Tuttavia ...
Straordinari estesa non risolverà i vostri problemi di pianificazione.
Sprintare per il traguardo è una cosa; sprintare per chilometri è un'altra. Straordinari estesi non risolveranno i vostri problemi di pianificazione. In realtà, ciò ha gravi conseguenze negative. DeMarco chiama straordinari estesi "una tecnica di riduzione-produttività  importante," che conduce alla ridotta qualità, alienazione del personale, aumento del turnover del personale, e l'uso inefficace del tempo durante il normale orario [DeMarco 2002] (p. 64).
Se si lavora fuori orario una settimana (qualunque "straordinario" si intende nella tua situazione), non funzionerà più lo straordinario della prossima settimana. Se vedo una squadra sprint più di una volta o due volte a trimestre, cerco problemi più profondi.

Risultati

Quando la tua squadra è Energized, c'è un senso di eccitazione e di cameratismo. Come gruppo, presta attenzione ai dettagli e cerca nuove opportunità di migliorare le vostre abitudini di lavoro. Si fanno progressi costanti ogni settimana e si sentono in grado di mantenere il progresso all'infinito. Apprezzi la salute sul progresso a breve termine e il sentire produttivo e di successo.

Controindicazioni

Energized Work non è una scusa per bighellonare. Generiamo fiducia mettendoci in una giornata di fiera del lavoro.
Alcune organizzazioni possono rendere l'Energized Programming difficile. Se l'organizzazione utilizza il numero di ore lavorate come metro per giudicare la dedizione, potrebbe essere meglio sacrificare l'Energized Work e fare lunghe ore di lavoro. La scelta tra la qualità della vita e l'avanzamento di carriera è una scelta personale che solo voi e la vostra famiglia potete fare.

Alternative

Alleati
Pair programming
Pianificazione di uscita
Se l'organizzazione rende l'Energized Work difficile, gli errori sono più probabili. Programmare in coppia potrebbe aiutare i programmatori stanchi a rimanere concentrati e catturare tutti gli altri errori. Ulteriori test potrebbero essere necessari per individuare i difetti extra. Se è possibile, aggiungete sempre un tempo di emergenza supplementare al vostro piano di rilascio per fixarlo.
La forma estrema di questo tipo di organizzazione è la "marcia della morte", tipo di organizzazione, che richiede (o "fortemente incoraggia") i dipendenti di lavorare per tante ore di straordinari settimana dopo settimana. Purtroppo, "progetti di marcia della morte sono la norma, non l'eccezione."[Yourdon] (p. ix).
Per aggiungere la beffa al danno, [DeMarco e Lister 2003] (p. 161) pesa: "Nella nostra esperienza, la caratteristica comune tra i progetti di "marcia della morte" è basso valore atteso. Sono progetti finalizzati a mettere fuori i prodotti di insignificanza monumentale. L'unica vera giustificazione per la marcia della morte è che con un valore così minuscolo, fare il progetto a costo normale sarebbe chiaramente comporterebbe costi che sono maggiori di benefici ... se il progetto è così essenziale, perché non può la società di trascorrere la tempo e denaro per farlo correttamente? "

Approfondimenti

Peopleware [DeMarco e Lister 1999] è un classico lavoro sulla motivazione del programmatore e la produttività. Dovrebbe essere in cima alla lista di lettura di ogni responsabile sviluppo software.
Sviluppo rapido [McConnell 1996] ha un capitolo su "Motivation" con un bel grafico di confronto motivazioni programmatore alle motivazioni dei dirigenti e la popolazione in generale.
Slack [DeMarco 2002] esamina gli effetti di straordinario estesa e troppi impegni.
Death March [Yourdon] descrive come sopravvivere ad un progetto di "marcia della morte".

mercoledì 2 aprile 2014

Principi di Continuous Delivery ( automatizzare i rilasci )

8 Principi di Continuous Delivery
1) Il processo per il rilascio / distribuzione del software DEVE essere ripetibile e affidabile . Questo porta al 2 ° principio ...

2) Automatizzare tutto! Una distribuzione manuale può mai essere descritta come ripetibile e affidabile (non se lo sto facendo!). Bisogna investire seriamente automatizzando tutte le mansioni che fate ripetitivamente, e questo tende ad accrescere la affidabilità.

3) Se qualcosa è difficile o faticosa, falla più spesso. Superficialmente questo suona stupido, ma in fondo questo significa che facendo qualcosa di difficoltoso, più spesso, vi porterà a migliorare, probabilmente automatizzando, e questo finirà per renderlo indolore e facile. Prendiamo ad esempio fare una distribuzione di uno schema di database. Se questo è difficile, si tende a non farlo molto spesso, ad evitarlo, facendolo forse una volta al mese. In realtà ciò che si dovrebbe fare è migliorare il processo di distribuzione delle implementazioni dello schema, diventando bravi a farlo, e farlo più spesso, ripetendolo anche una volta al giorno se necessario. Se fai qualcosa ogni giorno, troverai il modo di renderla migliore rispetto piuttosto che la si fa una volta al mese.

4) Tenere tutto codice sorgente versionato e sotto controllo - questo suona come un po strano oggi, ma parlo seriamente, chi tiene tutto il codice sorgente versionato? A quanto pare poche persone. Lo sapevate?

5) "Fatto" significa "Rilasciato". Ciò obbliga a lavorare su di un progetto fino a quando non è nelle mani degli utenti, e funziona correttamente. Non c'è, quindi, niente del tipo: "ho controllato nel mio codice quindi è fatto per quanto mi riguarda". Ho avuto la fortuna di lavorare con alcune squadre di software che con entusiasmo si assicuravano che le loro modifiche al codice stavano funzionando correttamente fino al momento in cui i loro cambiamenti erano in produzione, controllando, anche, il sistema live per assicurarsi che i loro cambiamenti erano avvenuti con successo. D'altra parte ho lavorato con squadre in cui la loro responsabilità finiva dopo aver controllato il loro codice per il VCS.

6) Costruire qualità! Prendete il tempo ed investite nelle metriche di qualità. Un progetto con buone metriche di qualità mirate (potremmo parlare di copertura di unit test, di code styling, di violazione delle regole, misure di complessità - o, preferibilmente, di tutto ) sarà sempre meglio di uno senza, e più facile da mantenere nel lungo termine.

7) Ognuno ha la responsabilità del il processo di rilascio. Un programma in esecuzione su un computer portatile di uno sviluppatore non sta andando a fare i soldi per la società. Allo stesso modo, un progetto senza un piano per la distribuzione non sarà mai pubblicato, e quindi non fa fare soldi. Le aziende fanno i soldi, da sempre, solo con prodotti rilasciati ai clienti, quindi, questo processo dovrebbe essere nell'interesse di tutti. Gli sviluppatori dovrebbero sviluppare progetti tenendo a mente come distribuirli. I project manager devono pianificare progetti con attenzione alla distribuzione. Tester dovrebbero verificare i difetti di distribuzione con la stessa cura e attenzione che impiegano per i bug del codice (e questo dovrebbe essere automatizzato e integrato nella attività di distribuzione stesso).

8) Migliorare continuamente. Non sedersi e aspettare che il sistema diventi obsoleto o impossibile da mantenere. Miglioramento continuo significa che il sistema sarà sempre in evoluzione e quindi più facile da cambiare quando ce ne sarà bisogno.

 Per usare al meglio questi principi
ci sono anche: 4 Best Practise di Continuos Delivery

 1) Compilare i binari solo una volta. Rimarreste attontiti per il numero di volte che ho visto gente ricompilare il codice tra un ambiente e l'altro. I binari devono essere compilati una sola volta e una sola volta. Il binario deve quindi essere conservato in un posto che è accessibile solo per il meccanismo di distribuzione e il meccanismo di distribuzione dovrebbe schierare lo stesso binario per ogni ambiente successivo ...

 2) Utilizzare esattamente lo stesso meccanismo per distribuire in ogni ambiente.
Sembra ovvio, ma ho visto sinceramente casi in cui sono state automatizzate le distribuzioni di Test e solo per le distribuzioni di produzione applicare procedure manuali. Ho visto anche casi in cui sono stati entrambi automatizzati, distribuzioni di Test e di produzione, ma in due lingue completamente diverse. Questo è ovviamente un lavoro da pazzi.

 3) Smoke test di rilascio. E' necessario non lasciare al caso che il rilascio sia un successo strepitoso, scrivere un test di funzioni base (smoke test) e includerli nel processo di distribuzione. Mi piace anche includere un semplice test diagnostico, tutto quello che è possibile fare per controllare va fatto e tracciato - si confronta un elenco di file e quello che ci si aspetta è di vedere la vostra distribuzione in quello che realmente finisce sul server. Io lo chiamo un test di diagnostica perché è un buon primo porto di scalo quando c'è un problema.

 4) Se qualcosa va storto, ferma la linea! Butta via e ricomincia da capo il processo, non modificare, non fare hack. Se si verifica un problema, non importa dove, scarta la distribuzione (cioè fai rollback), risolvi il problema correttamente, controllare nella versione del codice sorgente e ripeti il processo di distribuzione. Un sacco di gente dice che questo è impossibile, soprattutto se hai una finestra di interruzione per distribuire le cose nel vostro sistema live limitata, o se le modifiche di produzione finiscono nel bel mezzo della notte, mentre nessun altro è in giro per fixare adeguatamente la issue. Direi, invece, che questi argomenti colgono il punto. In primo luogo, se si dispone solo di una piccola finestra di interruzione, hacking del sistema live dovrebbe essere l'ultima cosa che vorrei fare, perché questo farà decadere tutti gli altri ambienti a meno di hackerare similmente tutti gli ambienti. In secondo luogo, la prossima volta che fate un rilascio, si può riprodurre il problema originale. In terzo luogo, se si sta facendo il rilascio nel bel mezzo della notte con nessuno intorno per risolvere i problemi, allora non stai prestando sufficiente attenzione al 7 ° principio di Continuos Delivery - Ognuno ha la responsabilità per il processo di rilascio. Almeno che non sia indispensabile, non mi consiglia di fare rilasci quando c'è la minima quantità di supporto disponibile e di personale, va semplicemente contro il buonsenso.

sabato 15 dicembre 2012

Easy Parallelism in .NET ? PLINQ !

come parallelizzare facilmente delle ricerche all'interno di una lista ? usando PLinQ cos'è ?
immaginate una ricerca su una lista semplice cosi come di seguito :

var customers = new[] {
 new Customer { ID = 1,  FirstName = "Sandeep"  , LastName = "Ramani" },
 new Customer { ID = 2,  FirstName = "Dharmik"  , LastName = "Chotaliya" },
 new Customer { ID = 3,  FirstName = "Nisar"    ,  LastName = "Kalia" } ,
 new Customer { ID = 4,  FirstName = "Ravi"     , LastName = "Mapara" } ,
 new Customer { ID = 5,  FirstName = "Hardik"   , LastName = "Mistry" }
 new Customer { ID = 6,  FirstName = "Sandy"    , LastName = "Ramani" },
 new Customer { ID = 7,  FirstName = "Jigar"    , LastName = "Shah" },
 new Customer { ID = 8,  FirstName = "Kaushal"  , LastName = "Parik" } ,
 new Customer { ID = 9,  FirstName = "Abhishek" , LastName = "Swarnker" } ,
 new Customer { ID = 10, FirstName = "Sanket"   , LastName = "Patel" }
 new Customer { ID = 11, FirstName = "Dinesh"   , LastName = "Prajapati" },
 new Customer { ID = 12, FirstName = "Jayesh"   , LastName = "Patel" },
 new Customer { ID = 13, FirstName = "Nimesh"   , LastName = "Mishra" } ,
 new Customer { ID = 14, FirstName = "Shiva"    , LastName = "Reddy" } ,
 new Customer { ID = 15, FirstName = "Jasmin"   , LastName = "Malviya" }
 new Customer { ID = 16, FirstName = "Haresh"   , LastName = "Bhanderi" },
 new Customer { ID = 17, FirstName = "Ankit"    , LastName = "Ramani" },
 new Customer { ID = 18, FirstName = "Sanket"   , LastName = "Shah" } ,
 new Customer { ID = 19, FirstName = "Amit"     , LastName = "Shah" } ,
 new Customer { ID = 20, FirstName = "Nilesh"   , LastName = "Soni" }       };

  List<Customer> result = new List<Customer>();
 foreach( Customer c in customers )
  if ( c.FirstName.StartWith("San") )
   result.add(c) ;
Come parallalelizzare semplicemente ed in maniera efficente questa ricerca ? 
semplicemente usando PLinQ e sostituendo il ciclo in questo modo : 


var results = from c in customers.AsParallel()
  where c.FirstName.StartsWith("San")
  select c;


Con la semplice aggiunta del metodo di estensione AsParallel(), il runtime .NET automaticamente parallelizza l'operazione in più nuclei. 

Limitazioni :
PLINQ funziona solo contro collezioni locali. Questo significa che se si sta utilizzando il provider LINQ sopra dati remoti, ad esempio LINQ to SQL o ADO.NET Entity Framework, allora non sei fortunato per questa versione. Poiché PLINQ divide la collection in più partizioni e li esegue in parallelo, i risultati che si otterrebbero da una query PLINQ non sarà nello stesso ordine dei risultati che si otterrebbero da una query LINQ eseguita o da un approccio tradizionale.

 Tuttavia, si può aggirare questo introducendo il metodo AsOrdered() nella tua query, che costringerà a un ordinamento specifico nei vostri risultati.




var results = from c in customers.AsParallel().AsOrdered()
  where c.FirstName.StartsWith("San")
  select c;



Tieni presente, tuttavia, che inserendo AsOrdered()per insiemi di grandi dimensioni, puoi perdere in termini di performance i guadagni di parallelizzazione ottenuti.

sabato 8 dicembre 2012

c# cross-platform Mobile tool 4 Android & iOS



 VSNomad Cool C# cross-platform Mobile tool 4 Android & iOS
http://www.youtube.com/watch?feature=player_embedded&v=W8Gto7JkCBk#!


Server VPS or Dedicated ? find the difference !!


Avete un pò le idee confuse riguardo la differenza tra un VPS – Server Virtuale ed un Server Dedicato? Bene, non preoccupatevi, oggi cercherò di chiarire le differenze e mettere fine ai vostri dubbi.

VPS – Server Virtuale (Virtual Private Server)

Un VPS e’ un server virtuale in funzione su un server fisico, le cui risorse sono divise tra piu’ utenti. Questo avviene grazie alla suddivisione di  un server in più macchine virtuali, separate ed isolate tra loro tramite apposite applicazioni, dando quindi ai propri clienti la possibilità di configurare e gestire in piena autonomia il proprio VPS.
E’ possibile scegliere il sistema operativo, le applicazioni da installare, ed è altamente personalizzabile.
E’ un’ottima forma di hosting dedicato, consigliata a chi possiede un sito di grandi dimensioni e/o di grande traffico, o chi vuole o deve gestire più siti contemporaneamente. E’ un hosting dedicato che grazie alla virtualizzazione permette di usufruire di ottime potenzialità a prezzi veramente convenienti.
Mi raccomando, prestate sempre attenzione ai prezzi che trovate in giro per la rete, ci sono una miriade di servizi ed offerte nel settore, più o meno convenienti. Se avete esperienze limitate con la gestione di un server, affidatevi ad un servizio “managed“.

Server Dedicato

E’ sicuramente la forma di hosting più personalizzabile e costosa che c’è, consigliata per siti estremamente trafficati e con un alto consumo di risorse. Si avrà la possibilità di gestire e configurare a proprio piacimento un intero server, e di utilizzare l’hardware noleggiato per il servizio che preferiamo. Numerosissime le offerte per server dedicati presenti in rete, con la possibilità di scegliere tra processori AMD e Intel di ultima generazione, scegliere quanta memoria ram acquistare, hard disk, etc.
Come per i VPS, stesso discorso riguardo la gestione. Per chi non ha valide conoscenze per l’amministrazione di un server, è consigliato affidarsi a servizi “managed“, ovvero gestiti interamente dallo staff dell’azienda hosting. (installazione, configurazione, gestione, aggiornamenti, patch sistema operativo, etc).

mercoledì 5 dicembre 2012

Git Automate Pull

Ciao

l'altro giorno mi sono ritrovato a dovere aggiornare tutti i 29 repository Git del un progetto su cui sto lavorando ... ODDIO che noia ... farli uno per uno .. allora mi sono detto ora automatizzo ... seee magari sembrava facile ma devo dire che ci ho messo un po a capire come poter passare al comando git pull le credenziali non dalla tastiera ed il tutto in un ciclo senza scrivere tutto a brodo che era brutto ... insomma alla fine il risultato è stato questo :

PullAll.bat

set ITEM_LIST=(repositoryFolder1 repositoryFolder2 repositoryFolder3  ... )
for %%i in %ITEM_LIST% do (
cd %%i
git pull | echo "<password>" > CON
cd ..
)

sabato 1 dicembre 2012

Object Cloning usando IL in C#


una delle cose più fastidiose che succede spesso nella programmazione in c# è quando ci si imbatte in un oggetto da modificare mantenendo in copia l'originale.
Questa difficoltà si manifesta poiché quasi sempre gli oggetti riassegnati vengono legati all'oggetto sorgente per riferimento*. 

Per risolvere questo noioso problema solitamente nei nostri progetti implementiamo dei metodi di "Clone" ossia dei metodi che ci copiano gli oggetti ( veriabili, classi, e quant'altro ) su un altro contenitore non collegato al primo.

A volte però ci sono oggetti per cui abbiamo grosse difficoltà perché magari non sono serializzabili o altro ... ma ecco che vi posto un po di metodologie che vi aiuteranno nella quasi totalità dei casi di Clonazione. 

IL (Intermediate Language) può essere utilizzato per clonare oggetti e non è affatto male, e può essere abbastanza performante. 

definiamo una Classe Person : 


  public class Person 
  { 
  private int _id; 
  private string _name; 
  private string _firstName; 
  private string _field1, _field2, _field3; 

  public Person() 
  { 

  } 

  public int ID 
  { 
  get { return _id; } 
  set { _id = value ; } 
  } 

  public string Name 
  { 
  get { return _name; } 
  set { _name = value ; } 
  } 

  public string FirstName 
  { 
  get { return _firstName; } 
  set { _firstName = value ; } 
  } 
  } 




Test Code: Il codice riportato di seguito è un bel pezzo di codice, leggete i commenti e capirete cosa vi è dichiarato.


  class Program 
  { 
  /// <summary> 
  /// Delegate handler that's used to compile the IL to. 
  /// (This delegate is standard in .net 3.5) 
  /// </summary> 
  /// <typeparam name="T1">Parameter Type</typeparam> 
  /// <typeparam name="TResult">Return Type</typeparam> 
  /// <param name="arg1">Argument</param> 
  /// <returns>Result</returns> 
  public delegate TResult Func<T1, TResult>(T1 arg1); 
  /// <summary> 
  /// This dictionary caches the delegates for each 'to-clone' type. 
  /// </summary> 
  static Dictionary<Type, Delegate> _cachedIL = new Dictionary<Type, Delegate>(); 

  /// <summary> 
  /// The Main method that's executed for the test. 
  /// </summary> 
  /// <param name="args"></param> 
  static void Main( string [] args) 
  { 
  DoCloningTest(1000); 
  DoCloningTest(10000); 
  DoCloningTest(100000); 
  //Commented because the test takes long ;) 
  //DoCloningTest(1000000); 

  Console.ReadKey(); 
  } 

  /// <summary> 
  /// Do the cloning test and printout the results. 
  /// </summary> 
  /// <param name="count">Number of items to clone</param> 
  private static void DoCloningTest( int count) 
  { 
  // Create timer class. 
  HiPerfTimer timer = new HiPerfTimer(); 
  double timeElapsedN = 0, timeElapsedR = 0, timeElapsedIL = 0; 

  Console.WriteLine( "--> Creating {0} objects..." , count); 
  timer.StartNew(); 
  List<Person> personsToClone = CreatePersonsList(count); 
  timer.Stop(); 
  Person temp = CloneObjectWithIL(personsToClone[0]); 
  temp = null ; 
  Console.WriteLine( "\tCreated objects in {0} seconds" , timer.Duration); 

  Console.WriteLine( "- Cloning Normal..." ); 
  List<Person> clonedPersons = new List<Person>(count); 
  timer.StartNew(); 
  foreach (Person p in personsToClone) 
  { 
  clonedPersons.Add(CloneNormal(p)); 
  } 
  timer.Stop(); 
  timeElapsedN = timer.Duration; 

  Console.WriteLine( "- Cloning IL..." ); 
  clonedPersons = new List<Person>(count); 
  timer.StartNew(); 
  foreach (Person p in personsToClone) 
  { 
  clonedPersons.Add(CloneObjectWithIL<Person>(p)); 
  } 
  timer.Stop(); 
  timeElapsedIL = timer.Duration; 

  Console.WriteLine( "- Cloning Reflection..." ); 
  clonedPersons = new List<Person>(count); 
  timer.StartNew(); 
  foreach (Person p in personsToClone) 
  { 
  clonedPersons.Add(CloneObjectWithReflection(p)); 
  } 
  timer.Stop(); 
  timeElapsedR = timer.Duration; 

  Console.WriteLine(); 
  Console.ForegroundColor = ConsoleColor.Green; 
  Console.WriteLine( "----------------------------------------" ); 
  Console.WriteLine( "Object count:\t\t{0}" , count); 
  Console.WriteLine( "Cloning Normal:\t\t{0:00.0000} s" , timeElapsedN); 
  Console.WriteLine( "Cloning IL:\t\t{0:00.0000} s" , timeElapsedIL); 
  Console.WriteLine( "Cloning Reflection:\t{0:00.0000} s" , timeElapsedR); 
  Console.WriteLine( "----------------------------------------" ); 
  Console.ResetColor(); 
  } 

  /// <summary> 
  /// Create a list of persons with random data and a given number of items. 
  /// </summary> 
  /// <param name="count">Number of persons to generate</param> 
  /// <returns>List of generated persons</returns> 
  private static List<Person> CreatePersonsList( int count) 
  { 
  Random r = new Random(Environment.TickCount); 
  List<Person> persons = new List<Person>(count); 
  for ( int i = 0; i < count; i++) 
  { 
  Person p = new Person(); 
  p.ID = r.Next(); 
  p.Name = string .Concat( "Slaets_" , r.Next()); 
  p.FirstName = string .Concat( "Filip_" , r.Next()); 
  persons.Add(p); 
  } 
  return persons; 
  } 

  /// <summary> 
  /// Clone one person object with reflection 
  /// </summary> 
  /// <param name="p">Person to clone</param> 
  /// <returns>Cloned person</returns> 
  private static Person CloneObjectWithReflection(Person p) 
  { 
  // Get all the fields of the type, also the privates. 
  FieldInfo[] fis = p.GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic); 
  // Create a new person object 
  Person newPerson = new Person(); 
  // Loop through all the fields and copy the information from the parameter class 
  // to the newPerson class. 
  foreach (FieldInfo fi in fis) 
  { 
  fi.SetValue(newPerson, fi.GetValue(p)); 
  } 
  // Return the cloned object. 
  return newPerson; 
  } 

  /// <summary> 
  /// Generic cloning method that clones an object using IL. 
  /// Only the first call of a certain type will hold back performance. 
  /// After the first call, the compiled IL is executed. 
  /// </summary> 
  /// <typeparam name="T">Type of object to clone</typeparam> 
  /// <param name="myObject">Object to clone</param> 
  /// <returns>Cloned object</returns> 
  private static T CloneObjectWithIL<T>(T myObject) 
  { 
  Delegate myExec = null ; 
  if (!_cachedIL.TryGetValue( typeof (T), out myExec)) 
  { 
  // Create ILGenerator 
  DynamicMethod dymMethod = new DynamicMethod( "DoClone" , typeof (T), new Type[] { typeof (T) }, true ); 
  ConstructorInfo cInfo = myObject.GetType().GetConstructor( new Type[] { }); 

  ILGenerator generator = dymMethod.GetILGenerator(); 

  LocalBuilder lbf = generator.DeclareLocal( typeof (T)); 
  //lbf.SetLocalSymInfo("_temp"); 

  generator.Emit(OpCodes.Newobj, cInfo); 
  generator.Emit(OpCodes.Stloc_0); 
  foreach (FieldInfo field in myObject.GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic)) 
  { 
  // Load the new object on the eval stack...  (currently 1 item on eval stack) 
  generator.Emit(OpCodes.Ldloc_0); 
  // Load initial object (parameter) (currently 2 items on eval stack) 
  generator.Emit(OpCodes.Ldarg_0); 
  // Replace value by field value (still currently 2 items on eval stack) 
  generator.Emit(OpCodes.Ldfld, field); 
  // Store the value of the top on the eval stack into the object underneath that value on the value stack. 
  // (0 items on eval stack) 
  generator.Emit(OpCodes.Stfld, field); 
  } 

  // Load new constructed obj on eval stack -> 1 item on stack 
  generator.Emit(OpCodes.Ldloc_0); 
  // Return constructed object.  --> 0 items on stack 
  generator.Emit(OpCodes.Ret); 

  myExec = dymMethod.CreateDelegate( typeof (Func<T, T>)); 
  _cachedIL.Add( typeof (T), myExec); 
  } 
  return ((Func<T, T>)myExec)(myObject); 
  } 

  /// <summary> 
  /// Clone a person object by manually typing the copy statements. 
  /// </summary> 
  /// <param name="p">Object to clone</param> 
  /// <returns>Cloned object</returns> 
  private static Person CloneNormal(Person p) 
  { 
  Person newPerson = new Person(); 
  newPerson.ID = p.ID; 
  newPerson.Name = p.Name; 
  newPerson.FirstName = p.FirstName; 
  return newPerson; 
  } 
  } 

La cosa fondamentale che fa è, creare un metodo dinamico, ottenere il ILGenerator, creare codice nel metodo, compilarlo per un delegato, ed eseguire il delegato. 

Il delegato è in cache cosi che l'IL non viene generato ogni volta che una clonazione dovrebbe avvenire, quindi perdiamo un solo poco tempo, quando il primo oggetto viene clonato (IL deve essere creato e compilato in fase di esecuzione). 

Speriamo che questo articolo sia utile per alcune persone se è così, fatemelo sapere. 

Saluti