Estate, caldo giornata light prima delle ferie... Tempo di statistiche.
So che siete in 3 e non ve ne pole frega' de meno, pero' quell'Amiga mi ha fatto sorridere...
Estate, caldo giornata light prima delle ferie... Tempo di statistiche.
So che siete in 3 e non ve ne pole frega' de meno, pero' quell'Amiga mi ha fatto sorridere...
Questo tweet di Paolo Attivissimo mi ha spinto a rispondere per scatenare una riflessione.
Ovvero: la guida autonoma e' davvero una buona soluzione all'idiozia umana?
Partiamo dalle premesse, attualmente la guida autonoma e' un pezzo di software. Complesso quanto vuoi ma software tradizionale. Anche perche' l'intelligenza artificiale sembra fare un po' la furbetta (in realta' fa quello per cui e' programmata ovvero per risolvere con minore fatica possibile il problema che le e' stato posto, pero' ancora non sembra essere applicabile a situazioni reali).
Dicevamo e' un pezzo di software. Il software ha sicuramente dei pregi che sono i tempi di risposta ed il rispetto delle regole. Sul contro abbiamo la scarsa flessibilita' e l'adattabilita' (cose in cui noi umani invece siamo piuttosto bravi).
Inoltre essendo codice per sua natura e' pieno zeppo di bug e vulnerabilita'. E' inevitabile.
Inoltre il software ha un difetto: funziona finche' non smette di funzionare (sembra banale detta cosi') e quando questo succede i danni tendono ad essere incalcolabili (ne sa qualcosa at&t)
Lo faccio presente:
Ora non mi ricordo l'ordine preciso anche perche' ci sono stati un paio di "rami" di gente che si accodava ad Attivissimo...
La risposta non mi ha convinto, ma per niente. Gli umani hanno difetti? Verissimo ma provate un attimo a prendere il controllo da remoto di un essere umano...
Perche' e' quello che succede con le auto. E non mi dite che in caso di guida autonoma farebbero piu' attenzione. La pressione del mercato e' troppo alta, succede in praticamente tutti gli ambiti, bisogna uscire ed uscire prima del concorrente. Il resto si vedra'.
Pensateci un attimo: guida autonoma vuol dire che un eventuale attaccante avrebbe il controllo completo di un aggeggio che gira per strada che pesa se va bene 1 tonnellata. Avete idea di cosa potrebbe combinare?
Ma ammettiamo per un attimo che non siano cosi' cazzoni. Anche a scriverlo con le migliori intenzioni possibili il sw contiene da 5 a 50 bug per migliaia di righe di codice (nel tweet avevo scritto per milione). La fonte? Exploiting Software pg. 14 I cui autori sono un ricercatore informatico ed uno scienziato informatico. Non esattamente i primi venuti.
Quindi un eventuale guida autonoma porterebbe con se migliaia di bug potenzialmente sfruttabili da un eventuale attaccante (considerando solo il sw e non le vulnerabilita' dovute ad altro per esempio librerie di terze parti oppure dovute al linguaggio di programmazione o ad una certa versione del compilatore*). Se poi l'auto e' pure connessa ad internet come oggi e' la prassi diciamo che ci sono buone basi per un disastro di proporzioni epiche.
Non metto tutti i tweet perche' non aggiungono niente al mio pensiero ma voglio lasciarvi con la mia conclusione:
Noi umani siamo bravi in compiti "non noiosi", e che richiedono capacita' di adattamento e flessibilita'. Siamo anche (abbastanza) bravi ad interpretare il comportamento delle altre persone, tipo il tizio che mette fuori la mano dal finestrino per indicare una svolta... Mentre il software e' bravo in compiti che richiedono ripetitivita' e tempi di reazione brevi (esattamente dove non siamo forti noi). Inoltre il software funziona bene in situazioni totalmente controllate (es. il sw di volo dove le rotte sono pianificate e se ci sono situazioni impreviste la palla passa ai piloti).
Per come la vedo io bisognerebbe combinare le due cose. Ovvero lasciare all'umano il controllo nella maggioranza delle situazioni, con il software pronto ad intervenire se l'umano sbaglia (p.es se cicca una frenata o se sta andando contro un muro). E non il viceversa (come l'autopilot tesla per intendersi). Inoltre per esempio il sw potrebbe prendere il controllo in situazioni come una coda (dove l'umano tende a distrarsi). Ovviamente il sw di controllo della macchina non deve essere in nessun modo connesso ad internet, deve essere un sistema isolato. Lo so che fa comodo aggiornarlo da remoto ma...
Oggi e' giornata di articoli visto che sono al secondo... Ma tant'e'. Ve la faro' molto breve: dobbiamo accedere ai servizi di $HOSTING_PAMPERS per deploy del codice, qualita' dello stesso (un'immane cagata imho) etc.
Questi sarchiaponi richiedono l'accesso in vpn tramite il client integrato di windows. Probabilmente c'e' una configurazione di questa macchina o qualche pacchetto che va in conflitto o sonasega per cui come cerco di aprire le impostazioni wpn vpn* di windows si pianta.
Ci son stato dietro per un po', poi ho deciso che siccome abbiamo un'astinenza tecnica e che ci avevo gia' perso troppo tempo dietro (e non mi pagano per questo, mi pagano per fare il mio lavoro) era giunto il momento di contattarli. Quello che seguira' sono le email vere scambiate tra me e l'astinenza. Ho solo cambiato un po' di nomi ma non ho inventato niente.
Buongiorno, vorremmo chiarimenti in merito al ticket aperto.
Scusate cosa intendete con "vpn1" e "vpn2"?
Al che ho deciso che era inutile proseguire, ho preso le responsabili (che fra parentesi leggevano in copia e si son fatte delle grasse risate) e ho chiesto loro, visto che comunque il mio pc ha un'hdd poco capiente, se era possibile cogliere la palla al balzo e sostituire l'hdd di questa macchina. Loro mi mandano l'hdd e IO faccio tutto il lavoro. Reinstallo la macchina da pulito (ho i dischi di ripristino) e si prova cosi'. Ovviamente ho chiuso il ticket...
Alla prossima!
14/08/2019 ogni tanto mi scappa una "w" al posto di "v" perche' e' un modo di scherzare che usiamo in ufficio (w pronunciata u alla martufello). Per cui un ipotetico "Giovanni" diventerebbe "Giouanni" (scritto "Giowanni")
Cosa sono le reflection? Sono sostanzialmente un modo per ottenere tutti i nomi dei metodi, ed eventualmente invocarli, senza sapere quali siano questi metodi. Tutti sanno da codice invocare il metodo "getPippo()" di una certa classe scrivendolo da codice, ed e' quello si fa praticamente di normale. Pero' ci sono delle situazioni per le quali non sai il nome dei metodi da invocare (oppure non li vuoi sapere perche' sono centinaia e devi invocarli tutti).
Java ci mette a disposizione uno strumento potentissimo (se usato bene): le reflections. E' possibile da un oggetto Classe ottenere i nomi dei suoi metodi (come oggetto Method). Tramite questi nomi, e' possibile invocarli per esempio, ma e' necessaria un'istanza di quella classe (ovviamente). E' anche possibile passare argomenti.
Il caso che tratteremo qui e' la generazione di un csv. Il caso che mi ha spinto a creare una classe generica e non una ad hoc e' che la tabella (e quindi l'entity) della quale devo generare il csv ha una pletora di campi (2 o 300 tipo) per cui la decisione era:
La domanda e' semiretorica anche perche' se non avessi scelto la seconda opzione non sarei qui a scrivere questo articolo. Per arrivarci pero' devo fare un po' di premesse:
La prima e' un metodo "generico" che formatta un oggetto usando istanceof (e restituisce una stringa) controllando pure se e' null o not. Se l'oggetto che mi passo in input e' null restituisco stringa vuota (questo perche' in un csv devi comunque mettere un ; se vuoi un campo vuoto).
Poi ci serve (o almeno a ME!!!) un metodo per convertire il camel case in stringa "normale" - questo perche' uso i nomi dei metodi come nomi di colonne (non vorrai mica fare un csv senza intestazione). Ma questo si fa facile - StringUtils di apache ci viene incontro con splitByCharacterTypeCamelCase il cui risultato passeremo al metodo join sempre di StringUtils (non metto screen abbiate pazienza).
Fatto questo io mi sono fatto un metodo di utilita' che data una classe restituisce tutti i suoi getters (escluso getClass che nel csv non serve)
Poi ci serve un metodo di utilita' che restituisca una stringa csv di una certa istanza (generica). Ho usato i generics perche' voglio potergli passare di tutto. Come si puo' notare per invocare un metodo tramite reflection si invoca il metodo invoke passandogli un'istanza che e' quella sulla quale il metodo verra' eseguito il risultato e' un object. Mi passo anche il separator (perche' voglio essere flessibile).
Come si puo' vedere viene invocato il metodo "formattatore" generico presentato all'inizio, questo evita che nella stringa ci sia il toString degli oggetti (che non e' molto human readable). Inoltre, sempre questo metodo, evita che ci siano dei campi sfalsati nel csv (dovuto alla presenza di campi null).
Vi risparmio la parte di scrittura su file perche' non interessante ai fini di questo articolo.
Alla prossima!
Quando si ha una lista in mano in Java 1.8 lo stream e' uno strumento molto potente, puo' essere usato per un fracco di cose tra cui la trasformazione della lista in qualcos'altro. Per evitare al programmatroto una .get(0) per prendere il primo (o uno qualsiasi) della lista sempre lo stream ti viene incontro con i metodi findFirst e findAny. La differenza? Il primo ti garantisce che l'elemento sia sempre quello.
Ovviamente suddetti metodi restituisco un Optional - a questo punto avete un po' di possibilita' davanti:
Qual'e' la differenza? orElse restituisce direttamente l'oggetto passato come parametro. Quindi potete tranquillamente passare null. orElseGet (come dice il nome) fa la get su quello che gli passate (quindi dev'essere un Supplier) e non devo dirvi (di nuovo) perche' non e' una buona idea passare null.
Se invece volete lanciare un'eccezione c'e' orElseThrow
Se non sapete cosa c'incastri l'immagine con il post andatevi a cercare cosa vuol dire "stream" in Inglese
Oggi mi sono imbattuto in questo esempio di fulgida programmazione. Ho censurato le parti "sensibili" (che potrebbero fare capire da dove proviene) e numerato i punti per facilitarvi la comprensione.
Ma seriamente?
Prima di tutto: che senso ha inizializzare una stringa con una data di default se poi non la usi.
Poi convertire una data in stringa e riconvertirla in data. Passare direttamente la data no eh? Troppo facile...
save => salva l'oggetto (nuovo) quindi se gia' esiste va in eccezione.
persist => si gestisce il fatto che l'oggetto possa esistere (equivalente di saveOrUpdate).
Che dire? Nulla ho finito le parole...
Ecco a voi un estratto da "Metello" di Vasco Pratolini. I motivi per i quali Ida viene considerata una buona ragazza...