Skip to content

Høydepunktene fra NDC Porto 2019

20190224_171600To dager med heftige workshops og en lineup utviklere bare kan drømme om ble en realitet for åtte Knowit-utviklere i februar. Les om høydepunktene Norwegian Developers Conference i Porto.

Norwegian Developers Conference (NDC) startet i Oslo i 2008 som et samarbeid mellom ProgramUtvikling og Microsoft Norge. Siden den gang har NDC blitt arrangert i ulike varianter i Sydney, London, København og Minnesota. Knowit har tidvis vært sponsor, og har i mange år hatt deltakere på konferansen. Denne gangen var vi ikke med på selve konferansen, men hadde i stedet fordelt oss på fire forskjellige workshops som gikk over to dager. Vi reiste ned flere dager før workshopene, og fikk god tid til å utforske byen.

Kvelden før konferansen var det fredagspils, og siden flyet gikk fra Flesland kl. 06:10 lørdag morgen hadde noen av oss bestemt seg for at det ikke var nødvendig å legge seg. Det var likevel en kvikk og opplagt gjeng som kom til Porto kl. 10:30, som man kan se på bildet fra første lunsj.

Image from iOS-2Etter at vi fant leiligheten, ruslet vi nedover mot elven og stedet hvor konferansen skulle holdes. Konferansesenteret ligger ved elven Douro, som deler Porto i to. Douro er også navnet på et av de mest kjente vindistriktene i Portugal, og i løpet av kvelden fikk vi smakt oss gjennom store deler av det portugisiske vinkartet. Det var også vinmesse i Porto denne helgen helgen, og søndag fortsatte dermed vårt dypdykk ned i den portugisiske vinen. Det viser seg at Portugal har et ganske stort utvalg av vin, i hvert fall før denne gjengen ble sluppet løs på vinmessen.

Image from iOS1Mandag tok de fleste av oss turen til Livrario Lello, som er en av Portugals eldste bokhandler. Den var et flott bygg med en veldig spenstig trapp med flere veiskiller i, nesten som i Harry Potters Galtvort. Etter bokhandelen dro vi til havet og så på fyrtårnet og bølgene ved utløpet til Douro og spiste litt. Og så dro vi videre og spiste litt mer.

20190225_161112Tirsdag var det klart for det vi egentlig reiste til Porto for. Vi har skrevet litt om hver av workshopene vi deltok på.

Workshop 1:
Practical Machine Learning with Functional Programming

Dette var en workshop holdt av Mathias Brandewinder, som ikke bare skulle ta for seg et nytt programmeringsspråk, men i tillegg begi seg ut på oppgaven å gi innsikt i maskinlæring. To veldig brede tema, og med bare to dager gikk tiden veldig fort, spesielt siden vi satt med mye praktisk arbeid. Av alle workshopene vi deltok på var kanskje dette workshopen med mest praktiske oppgaver i løpet av de to dagene.

Dag 1
Vi startet med en kjapp intro av F# som programmeringsspråk før vi ble kastet inn i maskinlæringsdelen av workshopen. Vi startet med klassifiseringsproblemer som vil si at gitt en input så ønsker man å identifisere hva inputen er. Eksempelvis med bildegjenkjenning av tall, så ønsker man å kunne identifisere hvilket tall et gitt bilde er. Dette var vår første oppgave for dagen. Neste oppgave kastet vi oss like gjerne over språkgjenkjenning med samme fremgangsmåte som vi hadde for tall. Bare at istedenfor et bilde fikk vi en tekststreng som skulle identifiseres.

Vi avsluttet dagen med en del teori rundt nevrale nettverk og fikk litt innføring i både hvordan det fungerer om man skal implementere det selv, i tillegg til litt innsikt i hvorfor det er ønskelig å bruke.

Dag 2
Vi fortsatte med nevrale nettverk, og videre så vi på regresjonsproblemer. Som vil si et problem hvor man ønsker å predikere en flytende verdi. Eks. Gitt en vin med flere egenskaper, hvor god er vinen? Dette var oppgaven vi skulle løse. For at algoritmen skulle predikere best mulig så vi på forskjellige egenskaper som var definert for vin i datasettet og hvordan de relaterte til hverandre. Det viste seg å være en korrelasjon mellom alkoholprosent og god vin. :D

Igjen avsluttet vi dagen med teori, hvor vi gikk gjennom blant annet overtilpasning ved bruk av trær som datastruktur, i tillegg til å gå gjennom en del konsepter og nyttige ressurser innenfor F#.

Oppsummering
I løpet av workshopen var det mer fokus på maskinlæring enn F#, men samtidig ble vi eksponert for ganske mange kule features ved F#. Blant annet hvordan språket bruker piping, type providers, pattern matching, functions og modules. Konklusjon: skal du lære det et nytt funksjonelt språk, kan F# være en gøy plass å starte.

Vi fikk litt tips til forskjellige ressurser vi kunne se på, både for F# og maskinlæring. Kaster med to linker her som kan være interessante om man har lyst å se mer på maskinlæring. Den første er tips til hvilken algoritme man burde ta i bruk for forskjellige problemer. Den andre er en side hvor man kan delta på maskinlæringskonkurranser: 

http://scikit-learn.org/stable/tutorial/machine_learning_map/index.html

https://www.kaggle.com/

Til F# finnes veldig mange gode ressurser, så kaster bare med en link til https://fsharp.org/ som er et godt startpunkt for videre utforsking.

Terningkast 5. Hvis det hadde vært tid til å gå gjennom alle oppgavene ville sekseren vært innen rekkevidde.

Workshop 2:
Building Great APIs from the Ground Up

Mike Amundsen hadde workshopen om hvordan man kan planlegge og bygge gode APIer. Første dagen var en gjennomgang av hvordan man planlegger og designer et API, mens dag to gikk ut på hvordan man kunne implementere og teste APIet man har designa.

Vi startet med et dypdykk i bakgrunnen og mulighetene til HTTP og REST før vi fikk presentert et tenkt kundecase. Kunden hadde skrevet ned noen tenkte specs til et API de trengte og vi skulle implementere det sammen i løpet av de neste dagene.

Det første steget var å finne ut storyen til APIet vi skulle lage. Dette innebar å finne ut hva kunden egentlig ville ha, noe som viste at spesifikasjonen var temmelig mangelfull, men vi fikk oppdatert denne til noe vi kunne bruke for å forstå hvordan APIet kom til å bli brukt. Selve designdelen var delt i fire etter dette:

  1. Bli enig om navngivning. Her må man høre med de forskjellige interessentene om hvilke ord de bruker på ting og tang, sånn at man kan bruke de samme ordene overalt. Dette blir alt for ofte bestemt av utviklere i stedet for av kunden, noe som fort kan skape forvirring. Schema.org ble nevnt som en nyttig ressurs for å skape et felles vokabular.
  2. Få tak i en liste av alle datapunkt. Hvilken data har man tilgang til og hvilken data trenger man skaffe?
  3. Visualiser APIet. Bruk et slags visualiseringsverktøy (ala UML. Vi brukte web sequence diagrams, https://www.websequencediagrams.com/ ) til å visualisere hvordan APIet skal oppføre seg, hvilke endepunkt det skal ha, osv.
  4. Profiler APIet. Bruk et API-profileringsspråk til å skrive ned hvilke datatyper og endepunkt man trenger. (Vi brukte alps.)

Når man implementerer et API er det viktig å tenke at APIet aldri kommer til å endre seg, mens koden bak kan endres ofte. Det er derfor veldig viktig å tenke API først og ikke bygge APIet for at det skal passe best mulig med datamodellen, men sånn at det gjør jobben sin best mulig. Hvis datamodellen endres senere vil man ikke måtte endre APIet, bare implementasjonen.

Man kan bruke Sketch - Prototype - Build-metodikken:

Sketch: skisser er laga for å bli kasta. Det er derfor veldig viktig å kunne skissere APIet kjapt og enkelt. Vi brukte https://app.apiary.io for å kjapt skissere opp hvordan APIet skal fungere. Ved hjelp av denne fikk vi skissert opp et enkelt API og satt opp mockservere som kan brukes til testing på ti minutter.

Prototype: Her brukte vi npm-pakken apib2swagger for å gjøre blueprintene våre om til swagger docs. Swagger fungerer bra både til å finne ut av småting som må endres og for å lage mer håndfaste mock-APIer som andre kan starte å utvikle mot.

Build: Når man skal bygge APIet er det smart å dele det opp i fire deler, DORR. Data-, object-, resource- og representation-modellene bør være adskilt.

Etter dette brukte vi Postman til å skrive tester av APIet og brukte Newman til å kjøre disse testene i kommandolinjen. Dette er altså noe man kan bruke til å automatisere APItestene i byggene.

Mike er en engasjerende og kunnskapsrik foredragsholder, så foredragsbolkene med bakgrunnsinfo ble virkelige dypdykk i materien. Dessverre ble workshopdelene ofte enten for grunnleggende til at vi fikk noe ut av de (lag et repo på github og push koden din), eller for avanserte til at det gikk an å få gjort noe annet enn å laste ned eksempelkoden på den tilmålte tiden (implementer APIet vi har diskutert i node på ti minutter).

Pros:

  • Solide forelesningsbolker
  • Foredragsholder vet mye og kan svare på alt

Cons:

  • Brukte mye tid på ting som "alle" kan (git) eller som er for spissa (heroku)
  • Dårlige praktiske oppgaver

Terningkast 3

Workshop 3:
Identity & Access Control for modern Applications and APIs using ASP.NET Core 2

Først fikk vi en historieleksjon om .NET-rammeverket og hvorfor man må etterstrebe, som et minimum, å kun være avhengig av .NET standard. Mye grunnet at versjon 4.8 av .NET Framework antas å være den siste (!).

.NET Core sin minimale og fleksible struktur, med Dependency Injection og påkobling mellom request/response pipeline, gir grunnlaget for sikker autentisering og autorisering av ressurser. Vi fikk prøvd oss på lab-oppgaver Dom og Brock hadde forberedt der vi i grove trekk tok for oss .NET Core sine APIer for autentisering (IAuthenticationService) og autorisering ([Authorize], Policy og Requirement).

Vi fikk en drøy time begge dagene på Lab-oppgavene. Oppgavene gikk i hovedsak ut på å sikre kommunikasjon mellom f.eks. en token server (IdentityServer), web-klient og web-API med bruk av protokollene OpenID Connect (oidc) og OAuth 2.0. Gøy! Oppgavene var kodet på forhånd slik at vi kunne kode de manglende brikkene, men var likevel gradvis utfordrende når kompleksiteten økte.

Det oppsto het debatt omkring hvordan man etablerer tillit mellom identitetstilbydere, slik som å stole på e-postadresse og navn fra Google-autentisering og hvordan disse flettes inn tilpassede identitetsprinsipper.

Å sentralisere identitetshåndtering gir mulighet for – og utfordringer i – single sign-on, single sign-off, federering og home realm discovery. For å komme dit må man i korte trekk

  • Standardisere kommunikasjon av tokens over JSON Web Tokens (JWT) slik at de ulike ressursene kan samhandle.
  • Identifisere forskjellen mellom beskyttede og ubeskyttede klienter som legger føringer på valg av token flows.
  • Code flow → Eksempelvis for API-klienter
  • Hybrid flow → Eksempelvis for ubeskyttede klienter slik som native apps og SPAs
  • Håndtering av livssyklus for token gjennom refresh-tokens og mulighet for (umiddelbar) token revocation

Spørsmålene man stiller seg før man velger løsning kan være: Har jeg mulighet til å umiddelbart trekke tilbake tilgang for en klient? Hva må jeg kunne gjøre hvis et token kommer på avveie? Er det OK at jeg lar tokenet være gyldig i 14 dager? På hvilken måte kan jeg beskytte klienter som i utgangspunktet er ubeskyttet?

Til tross for høyt nivå på foredragsdelen, og aktivering av deltakerne gjennom Q&A, mener vi at det med fordel kunne vært satt av mer tid til koding under workshopen.

Vi hadde lite pauser i løpet av dagen, og det hendte at vi ble sliten av alt som skulle tas inn. Når workshopene ble avsluttet en time før planlagt tid begge dager, mener vi tiden kunne vært bedre disponert med å ta en ekstra pause og bruke mer tid på koding og oppfølging.

Pros:

  • Solide forelesningsbolker
  • Gode lab-oppgaver
  • Kule demoer

Cons:

  • Tidvis dårlig luft og varmt lokale
  • Lite tid til kodeing og spørring

Terningskast 4 og 1/2

Workshop 4:
From Design Patterns to universal abstractions

20190227_160407

Workshopen ble holdt av Microsoft MVP, forfatter og foredragsholder Mark Seemann. En kjent figur innenfor .NET (og NDC)-miljøet. Fra første stund gjorde han det klart at, til tross for at de andre workshoppene på NDC var “helt greie”, så mente han at dette kom til og bli en annerledes workshop som potensielt var “life changing”. Mens de andre fokuserte på å lære en spesifikk teknologi som om 10 år vil være utdatert, ville denne lære vekk konsepter som kom til å vare livet ut. Med dette var lista lagt.

Mark åpnet med å snakke om Humane code, og viktigheten med å skrive kode som er enkel for et menneske å forstå. Det finnes mange måter å gjøre dette på, men et av hjelpemidlene vi har, og som Mark fokuserte mye på, var abstraksjon. Han mener abstraksjon ofte har et dårlig rykte og at mange tenker at abstraksjon gjør koden mer verbos, vag og kompleks. Med ekte abstraksjon er ikke dette riktig, og er man presis nok skapes et nytt semantisk nivå som gjemmer alle unødvendige detaljer og gjør at lesere av koden ikke trenger å se hva som skjer i en metode/funksjon for å vite hva denne gjør.

Any fool can write code that a computer can understand. Good programmers write code that humans can understand. – Martin Fowler

Mark foreleste en del om visse grener av matematikk som lå til grunn for teknikkene vi brukte i workshopen. Dag 1 gikk veldig greit for seg, og det tekniske nivået som krevdes var relativt lavt. Han advarte dog om at nivået kom til å øke lineært, noe vi fikk kjenne på slutten av dag 2 der hjernen var litt mer utmattet.

Dag 1 bestod i hovedsak av å gi praktiske eksempler på “composite design pattern”, samt å matematisk forklare hva monoids var. Hvis en klasse var en monoid kunne man garantere visse egenskaper, som f.eks. at klassen alltid kunne brukes i et composite pattern. Gjennom hele workshopen dro han mye inspirasjon fra teknikker og mønster fra funksjonell programmering og brukte mye tid på å vise hvordan man kunne overføre dette til et objektorientert paradigme, der han kodet i C#.

Dag 2 begynte med å vise en veldig dårlig kodesnutt som vi gjennom resten av dagen skulle refaktorere ved å bruke teknikkene fra foregående dag, og andre teknikker vi gikk gjennom resten av dagen. Han gikk trinnvis gjennom mange iterasjoner av koden med mulige løsningsforslag der han hver gang introduserte et nytt matematisk konsept med tilhørende praktiske oppgaver. Vi gikk gjennom konsepter som Functors, Monads, Visitor Design Pattern og en rant om hvordan konseptet “null” er djevelens verk som har kostet milliarder av kroner. Hans løsning på dette var å implementere en versjon av Maybe-konseptet fra funksjonell programmering i C#, som skulle eliminere null, og heller gi et objekt som enten ikke hadde en verdi (Nothing) eller hadde en verdi (Just<T>), der T er en vilkårlig type. En kan lese mer om disse konseptene et annet sted enn her, da det krever mer enn et avsnitt for å forklare dette på en god måte, men man kan trygt si at vi var slitne da dagen var over. Den refaktorerte kodesnutten var nå blitt veldig leselig på overflaten, så lenge du ikke gikk under panseret for å se hvilken 3-hodet drage som gjemte seg der.

Oppsummert så ga denne workshopen en introduksjon i hvordan man kan ta nytte av teknikker kjent fra matematikk og funksjonell programmering for å skrive kode som er lettere å lese, og som gir mindre rom for feil. Mark klarer på en god måte å få frem budskapet i workshopen, og har en veldig god flyt både på dag 1 og 2. Til tross for dette vil vi, etter vår mening, si at fordelene man får ikke veier opp tiden det tar å implementere disse teknikkene i objektorientert programmering. Tiden er nok bedre brukt til å ta i bruk et funksjonelt programmeringsspråk som F#, der man får dette gratis.

Terningkast 4


Kvaliteten på workshopene opplevdes av deltakerne som alt fra midt-på-treeren til sterk femmer. Vi hadde egentlig forventet litt bedre kvalitet fra NDC jevnt over, og det kunne med fordel vært noen workshops som går mer i dybden. Neste gang vi drar på NDC kan det hende vi prioriterer å gå på selve konferansen, som vi stort sett har vært veldig fornøyd med.