Bitrock a Devoxx UK 2024

Devoxx UK 2024

Abbracciamo l’innovazione e la collaborazione

Bitrock è lieta di annunciare la propria partecipazione a Devoxx UK 2024, che si è tenuta a Londra dall’8 al 10 maggio. Devoxx UK è una conferenza organizzata dagli sviluppatori per gli sviluppatori, rinomata per il suo programma completo, che copre una vasta gamma di argomenti, dallo sviluppo del software agli ultimi progressi tecnologici. La conferenza di quest’anno ha ospitato 170 sessioni di approfondimento e 130 relatori di spicco, e ciò lo ha reso un evento imperdibile per chiunque operi nel settore tecnologico.

Come parte di un’azienda impegnata a promuovere l’innovazione, i bitrockers sono stati entusiasti di unirsi a questa comunità dinamica e di imparare dai leader del settore! Con numerosi interventi in contemporanea, ecco alcuni punti salienti degli interventi che hanno apprezzato di più.

Clean Modular Architecture

Quanti sviluppatori non conoscono Victor Rentea? Si potrebbe dire pochissimi. Chi lo conosce sa sicuramente che i suoi talk sono uno spettacolo, ma al di là dello spettacolo, Victor è un forte sostenitore del Clean Code, del refactoring e dello unit testing. Ci si potrebbe chiedere cosa abbiano a che fare queste tre cose con l’architettura delle applicazioni.

Spoiler: hanno molto in comune. Attenzione, chi ritiene inutili i test automatizzati può passare alla sezione successiva

Facendo un passo indietro, molti sviluppatori tendono a essere cauti quando scrivono nuovo codice. Gli sviluppatori senior rimproverano ai junior di astrarre il codice troppo presto o di ingegnerizzare troppo le funzioni semplici (K.I.S.S.). Giusto? Sbagliato? Come sempre, la risposta è “dipende”. Se apprezzate i test automatizzati, conoscete sicuramente il ciclo RED-GREEN-REFACTOR reso famoso da Kent Beck. Quindi, scriviamo nuovo codice, lo esercitiamo con i test e poi apportiamo tutte le modifiche necessarie, poiché ci saranno i test a garantire la funzionalità.

Parlando di architettura, anche qui la risposta è “dipende”. Qualche anno fa, le applicazioni monolitiche sono state sempre più criticate perché problematiche in termini di lentezza e scalabilità, ad esempio. La soluzione è stata l’utilizzo di microservizi: leggeri, scalabili, veloci da sviluppare da parte di diversi piccoli team… la soluzione a tutti i problemi, giusto? Non è così semplice: i microservizi comportano una maggiore complessità in termini di gestione e orchestrazione. Le aziende se ne sono accorte. Alcune hanno fatto uno o più passi indietro alla ricerca di alternative.

E se si potesse creare un monolite modulare? Un Modulith.

Niente di nuovo. Niente di mai visto prima. Piuttosto, solo un punto di vista diverso.Prendendo un’applicazione web tradizionale scritta con Spring, la struttura dei package sarebbe simile a questa:

Questo è un raggruppamento funzionale dei vari componenti. Tuttavia, provando a raggrupparli per dominio, il risultato potrebbe essere:

Ognuno di questi package dovrebbe avere le seguenti caratteristiche:

  • caratteristiche di business (valore per l’utente)
  • implementazione privata (modello di dominio + logica)
  • API pubbliche
    • interne, per altri moduli (chiamate di metodi o eventi)
    • esterne, per altri sistemi (REST, Kafka)
  • tabelle di database private

Ciascuno di questi moduli potrebbe essere gestito da un singolo team. Questa struttura consentirebbe di estrarre rapidamente un modulo, se necessario. Prima abbiamo parlato di refactoring; questo è il refactoring applicato all’architettura.

Abbiamo anche parlato di test. Avete mai sentito parlare di ArchUnit? È una libreria che può essere usata per eseguire rapidamente test unitari sull’architettura. Le caratteristiche dei moduli descritti sopra possono essere definite con ArchUnit.

Ora immaginate:

  • un unico repository
  • tutti i team che lavorano sullo stesso repository, ma ognuno su un dominio/modulo dedicato
  • zero tempo di integrazione (è solo refactoring di codice Java)
  • comunicazione immediata tra i moduli
  • distribuzione di un singolo artefatto
  • test che mostrano immediatamente se un modulo non soddisfa più determinate caratteristiche
  • in caso di necessità, un modulo può essere estratto facilmente

Se sembra molto complesso realizzare tutto questo, non lo è affatto. Richiede solo il coraggio di provare un approccio diverso. Spring aiuta con il progetto Spring Modulith, che fornisce già tutte le idee presentate qui, in particolare i test architetturali. Anche l’implementazione di altri framework, come Quarkus, non è complicata.

GraalVM e le immagini native

GraalVM e le immagini native in generale sono state oggetto di alcuni interventi al Devoxx UK in cui si è cercato di spiegarne i pro e i contro, alcune caratteristiche da tenere in considerazione e alcuni casi d’uso di successo.

GraalVM è un JVM ad alte prestazioni che esegue applicazioni scritte in Java, JavaScript, Python, R, Ruby e altri linguaggi. Include anche un compilatore Just-In-Time (JIT) per creare immagini native, un tipo di file eseguibile creato tramite compilazione ahead-of-time (AOT). Ciò significa che il codice dell’applicazione viene compilato in codice macchina prima che l’applicazione venga eseguita. 

Si tratta di un’ottima scelta per le funzioni serverless in cui il tempo di avvio è molto importante.

I vantaggi della combinazione di immagini native e funzioni serverless sono:

  • Riduzione degli avvii “a freddo”: le immagini native eliminano la necessità di lanciare la JVM, riducendo significativamente i tempi di avvio a freddo.
  • Le immagini native sono più piccole delle loro controparti JVM, il che comporta un minore utilizzo della memoria e costi potenzialmente ridotti.
  • Poiché il codice è già compilato, l’esecuzione diventa più veloce rispetto all’esecuzione di bytecode attraverso la JVM.

Le immagini native presentano anche alcune limitazioni quando si tratta di framework e reflection:

  • Assunzione “Mondo chiuso”: opera sotto un presupposto di un mondo chiuso, il che significa che deve essere informato esplicitamente sugli aspetti dinamici del codice. Ciò include la reflection, le risorse, la serializzazione e i proxy dinamici.
  • Classpath dell’applicazione: il classpath dell’applicazione è fisso al momento della compilazione. Non è possibile aggiungere o rimuovere dinamicamente classi in fase di esecuzione in un’immagine nativa.
  • Debug limitato: il debug delle immagini native può essere più impegnativo rispetto alle applicazioni JVM tradizionali.
  • Considerazioni sui framework: alcuni framework, come Spring con configurazioni specifiche del profilo tramite @Profile, potrebbero avere funzionalità limitate a causa dell’assunzione di un mondo chiuso.
  • Librerie di terze parti: il supporto per le immagini native non è garantito.

Queste limitazioni possono avere un impatto sulla flessibilità dei framework quando si utilizzano le immagini native di GraalVM. Tuttavia, esistono tecniche per mitigare questi problemi, come l’uso della reflection statica o la configurazione esplicita degli aspetti dinamici dell’applicazione.

Come non strangolare i colleghi: Risolvere i conflitti con la collaborazione

Durante il Devoxx non si è parlato solo di codice e tecnologia. La conferenza ha ospitato anche interventi su come migliorare la comunicazione, le relazioni e diventare un buon mentore. L’intervento di Arthur Doler è stato molto interessante. Ha dato consigli utili e ha parlato della psicologia che sta dietro alla gestione dei conflitti sul posto di lavoro.

Sicurezza psicologica: La ricetta segreta

Un punto chiave del discorso di Arthur è stata l’importanza della sicurezza psicologica, un concetto sviluppato dalla professoressa di Harvard Amy Edmondson. Questo non è solo una buzzword; è il fondamento di un team unito. Questa parola super importante significa che tutti si sentono sicuri di esprimersi senza timore di ritorsioni o imbarazzi. Immagina un luogo di lavoro che incoraggia il dialogo aperto e il conflitto costruttivo dove le idee fluiscono liberamente, gli errori vengono discussi e l’apprendimento è continuo.

Amy Edmondson ha dimostrato il fondamento di questa teoria con uno studio su delle équipe di medici. In particolare, l’autrice scoprì che team che lavoravano spesso insieme e quindi collaboravano di più, avevano tassi di errore più elevati. Scoprì poi che questo risultato era conseguenza di una maggiore apertura sul condividere i propri errori. Questa cultura della trasparenza ha portato a un miglioramento continuo e a prestazioni eccellenti. Un potente promemoria del fatto che ammettere gli errori non è un segno di debolezza, non credete?

Gestione delle emozioni nei conflitti

Arthur ha smontato l’idea comune che trattenere le emozioni nel conflitto porti a risultati migliori. Contrariamente a quanto si crede, non aiuta, anzi, può peggiorare le cose. Ci ha invece esortato a portare le emozioni in primo piano e a discuterne apertamente (ad esempio comunicare in retrospettiva “questo rilascio mi spaventa”). Questo approccio favorisce la comprensione e allenta la tensione.

Qual è il vostro stile per la gestione dei conflitti?

L’affondo che Arthur ha fatto delineando gli stili che possono essere utilizzati durante un conflitto è stata illuminante. Ci ha introdotto al “Dual Concern Model”, che delinea cinque stili basati sulla preoccupazione per sé e per gli altri:

  • Avoiding – schivare il problema, sperando che si risolva da solo.
  • Yielding – cedere agli altri per mantenere la pace
  • Fighting – si tratta di vincere a tutti i costi, l’estremo della competizione
  • Cooperating – cerca soluzioni che vadano a beneficio di tutti
  • Conciliating – mescola elementi di Fighting e Yielding

Concentrarsi su obiettivi comuni è essenziale anche nei conflitti. L’idea è quella di ottenere uno scenario dove tutti i partecipanti al conflitto ottengono una piccola vittoria, ovvero che la propria idea venga accolta in parte. Tuttavia, è anche importante scegliere le proprie battaglie con saggezza, dando priorità ai conflitti che sono in linea con i vostri valori, per garantire che i vostri sforzi abbiano un impatto.

Mosse di potere per tutti

Anche se non avete un ruolo di leadership, potete avere un grande impatto. Ha sottolineato che ogni voce è importante. Sostenere con costanza i cambiamenti positivi, anche se si è solo un singolo collaboratore, può cambiare le dinamiche del team nel tempo. La chiave è rimanere un membro in regola all’interno del team. L’influenza funziona meglio dall’interno, quindi rimanete impegnati e in contatto con il vostro team.

La comprensione delle dinamiche di potere è fondamentale. Che abbiate o meno il potere, riconoscere la sua influenza vi aiuta a gestire i conflitti in modo più efficace. Arthur ci ha incoraggiato ad affrontare i conflitti con curiosità e una mentalità collaborativa. Spesso gli altri seguiranno il vostro esempio quando dimostrerete un impegno per la comprensione reciproca.

Concentrarsi su obiettivi comuni è essenziale anche nei disaccordi. Tuttavia, è anche importante scegliere le proprie battaglie con saggezza, dando priorità ai conflitti che sono in linea con i vostri valori per garantire che i vostri sforzi abbiano un impatto.

Tirando le somme

L’intervento di Arthur Doler ci ha ricordato che il conflitto non è un nemesi da sconfiggere, ma un alleato. Promuovendo la sicurezza psicologica, accogliendo le nostre emozioni e gestendo strategicamente il conflitto, possiamo trasformare il cuore del nostro team in termini di collaborazione e innovazione. Fare propri questi spunti permette di creare un ambiente di lavoro dove ogni voce è ascoltata, ogni idea valorizzata e ogni conflitto diventa un piccolo passo per comprendere meglio l’altro.

Mettere in sicurezza la supply chain

La sicurezza è un argomento sempreverde e sicuramente non poteva mancare al DevoxxUK 24!

La sicurezza abbraccia un ampio spettro del nostro mondo IT, e alcuni aspetti sono più complessi di altri perché coinvolgono più parti del nostro software. Le supply chain sono una di queste.

Una supply chain può essere brevemente descritta come l’insieme di dipendenze, procedure, strumenti e persone necessarie per sviluppare, costruire e distribuire un’applicazione.

Uno dei primi interventi è stato quello sulla sicurezza della supply chain, tenuto da Thomas Vitale. L’intervento è stato molto pratico e ha citato alcuni strumenti che possono essere utilizzati in ogni fase della catena di fornitura per renderla più sicura:

  • Codice sorgente: come avremo notato, i commit di git mancano di autenticazione, quindi chiunque può fare commit come chiunque. Esistono molte soluzioni, come gitsign (che supporta OpenID) o semplicemente git, che permettono di firmare i commit con SSH o GPG. 
  • Gestione delle dipendenze: iniettare un repository dannoso da cui includere le dipendenze può essere un modo per introdurre codice dannoso nel nostro software. Ci sono modi molto sottili che permettono questo attacco abusando del sistema di repository discovery dei nostri strumenti di gestione delle dipendenze (maven, gradle, ecc.). Una soluzione per mantenere pulite le nostre dipendenze sono le SBOM (Software Bill Of Materials) che possono essere l’input degli scanner di vulnerabilità e affrontare anche i problemi di integrità. CycloneDX è uno degli strumenti più utilizzati per generare SBOM.
  • Build: il passaggio al nativo, come accennato in un altro capitolo di questo articolo, ha molti vantaggi. Uno di questi, spesso messo in ombra, è che un binario nativo offre meno superficie di attacco. Un jar java include tutto il codice delle dipendenze, che anche se non viene utilizzato è presente e, se si tratta di codice vulnerabile, è pronto per essere sfruttato. D’altra parte, il binario nativo si ottiene solo compilando il codice raggiungibile dall’applicazione. Ovviamente questo non può giustificare una migrazione al nativo, ma è sicuramente un “nice to have”! Buildpacks è uno strumento che può essere utilizzato per gestire la compilazione di immagini native.
  • Artefatti sicuri da distribuire: Cosign è uno strumento che consente di firmare crittograficamente qualsiasi elemento discusso in precedenza: file SBOM, immagini, binari, ecc. Convalidando queste firme possiamo essere sicuri che gli artefatti distribuiti sono quelli che abbiamo costruito in precedenza e non sono stati sostituiti o manomessi in alcun modo.

Come si vede, ci sono molti strumenti a disposizione. La sfida consiste spesso nell’instillare questa cultura nelle nostre procedure quotidiane.

Capire il clamore che c’è intorno a Rust

Rust ha guadagnato popolarità per il suo approccio innovativo alla gestione della memoria e per la sua capacità di fornire sia sicurezza che prestazioni. Eliminando bug comuni come i de-referenziamenti dei puntatori nulli e i data race attraverso il suo sistema di proprietà, Rust garantisce la sicurezza della memoria senza sacrificare la velocità. Approfondiamo il modello di proprietà di Rust e alcune delle sue caratteristiche chiave che lo rendono un linguaggio potente e sicuro.

Sistema di proprietà

In Rust, ogni valore ha un singolo proprietario. Quando il proprietario esce dallo scope, Rust libera automaticamente la memoria associata. Questo garantisce la sicurezza della memoria senza un garbage collector.

Ecco un semplice esempio:

In questo snippet, le variabili s1 e s3 sono proprietarie dei loro valori. Quando queste variabili escono dallo scope, Rust libera la loro memoria. Se la proprietà di una variabile viene trasferita, come nel caso di s2, la variabile originale non può essere utilizzata a meno che la proprietà non venga trasferita nuovamente o clonata.

Gestione dei riferimenti e borrowing

Il sistema di prestito di Rust consente di fare riferimento a valori senza assumerne la proprietà. Questo garantisce la sicurezza della memoria, consentendo al contempo riferimenti multipli:

In questo caso, calculate_length prende in prestito s1 senza assumerne la proprietà, consentendo a s1 di essere utilizzata altrove.

Altre caratteristiche chiave

Stringhe codificate UTF-8: Tutte le stringhe in Rust sono codificate UTF-8 per impostazione predefinita, semplificando l’internazionalizzazione.

Enum e pattern matching: gli enum di Rust possono contenere dati e sono utilizzati ampiamente con il pattern matching, consentendo un codice chiaro e conciso:

Tipi di opzione e di risultato: Rust sostituisce i null con il tipo Option e le eccezioni con il tipo Result, integrando queste possibilità nel sistema dei tipi per garantire che siano gestite correttamente.
Tratti e strutture: Rust utilizza i tratti per definire comportamenti condivisi e le strutture per creare tipi di dati complessi. I tratti possono essere implementati da più tipi, in modo simile alle interfacce di altri linguaggi.

Adozione ed ecosistema di Rust

Dal 2016 Rust è il linguaggio più amato su Stack Overflow. È stato adottato da aziende importanti come Google, Apple e Amazon ed è ora supportato dal kernel Linux. Nonostante i suoi punti di forza, Rust presenta alcuni svantaggi, come una libreria standard più piccola e tempi di compilazione più lunghi a causa dei controlli di sicurezza estesi.

Per iniziare

Per chi è interessato a imparare Rust, il libro ufficiale di Rust, disponibile gratuitamente online, è un ottimo punto di partenza. Piattaforme online come Exorcism offrono sfide pratiche di codifica e la partecipazione a Discord della comunità di Rust può fornire ulteriore supporto e risorse.

In sintesi, il sistema di proprietà di Rust e le sue caratteristiche moderne lo rendono una scelta convincente per costruire software sicuro, efficiente e affidabile. Sia che stiate sviluppando applicazioni web, sistemi embedded o qualsiasi altra cosa, Rust offre strumenti potenti per aiutarvi a scrivere codice di alta qualità.

Conclusioni

Devoxx UK 2024 è stato un evento imperdibile! È stata una miniera d’oro per tutti coloro che vogliono rimanere aggiornati sulla tecnologia, . relatori di prim’ordine provenienti da tutto il mondo hanno tenuto discorsi perspicaci sugli ultimi progressi. ma Devoxx uk non è stato solo conferenze! È stato uno spasso, un’occasione per entrare in contatto con l’incredibile comunità di sviluppatori proprio qui nel Regno Unito. Non vediamo l’ora di partecipare al Devoxx uk 2025!


Authors: Cristian Bertuccioli (Senior Software Engineer and Scrum Master Certified); Marco Righi (Scala Developer); Davide Pavan (Software Engineer); Carmelo Calabrò (Senior Developer); Gianluca Cavalli (Software Engineer) @ Bitrock

Vuoi saperne di più sui nostri servizi? Compila il modulo e fissa un incontro con il nostro team!

Skip to content