Software that Fits in Your Head • Dan North • GOTO 2016

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
there we go the round of applause for that man oh this is suddenly much louder than I was expecting I'll speak very softly okay so the goal of software development then is minimizing lead time to business impact it turns out that the minimizing lead time to business impact isn't that hard okay you can minimize lead time to visit impact by mostly by shouting at people that works you can beat them I mean I wouldn't suggest beating them but you know you can put people under insane amounts of pressure and that will allow you to minimize lead time to business impact once okay unlikely to happen more than once certainly unlikely to happen more than twice okay because either all those people are just exhausted now or they've quit or you've been arrested or something's happened okay so that's not the hardest thing the hardest thing is sustainably minimizing lead time to business impact and that is the goal of the system of work that we call software development we want to be able to create business impact at will in a very short amount of time sustainably okay and once you start thinking in these terms a number of things become apparent so the first thing that becomes apparent is this the goal is not producing software we call ourselves software engineers and that's like a plumber calling themselves a pipe engineer right the purpose of plumbing isn't pipes the purpose of plumbing is heating and water okay the purpose of what we do is information we used to call it information technology applying technology to information but that wasn't cool enough so now we're software engineers and some of us are software craftsman which i think is kind of cute but I'm not I'm not a fan of those kind of terms because the software isn't the point okay business impact is the point so it produces an interesting word it's a latin word from prod ra which means to make things and and we see it a nightmare replaces we see see the word what word versions of this word in different places so production is the same root as produce and productive so all of these are from the root Prada rate okay and what that what that suggests is it is building things so if I'm making widgets in a factory I'm producing things right that's productive and if I produce more widgets in a given amount of time or produce more cars on a production line there's that word again right then then that's better okay so the idea is that I want to make more widgets but we don't want to make more software we want to make business impact and we want to make business impact quickly and quickly suggest less software and so we have this kind of this this awkward a conflict which is that productive is not the same thing as effective which is a shame because for decades we've been talking about software productivity metrics and measuring productivity and talking about measuring productivity and it's the wrong thing okay we shouldn't be looking at measuring productivity and the problem is this code is not the asset we think of code as an asset we use languages like our legacy even legacy code our legacy legacy system legacy is a thing of value you leave to the next generation that's your legacy okay so we think of software as valuable we talk about technical debt because good software is an asset bad software is debt right so we think of code as an asset code isn't an asset okay this is the uncomfortable truth code is not an asset code is cost okay code is the cost of getting the business impact the business impact is the thing we care about okay and there's lots and lots of types of cost code has cost in lots of different ways there's the basic writing cost the cost of having human beings I dearly highly paid human beings okay you're a highly paid human beings right highly paid human beings I'm writing code for every time what 10 people in my team every single day that's 10 people days of cost ok so a conservative estimate about $1,000 a day fully loaded cost for a human being so it's about $10,000 a day that's 50,000 dollars a week there you go is just my cost to start writing stuff so that's that's the obvious that's the obvious visible cost then there's a bunch of other costs waiting for code costs there's equal cost of delay okay and so cost of delay is this is say I have a need and the need is I need some information and given that information I can make good decisions there's no there's a buying decision I have to make every day I have to buy certain things every day and if I have that information I'll maker I can know exactly how much of the thing to buy if I don't have that information I have to guess and every day I guess either slightly high or slightly low because I'm guessing and that cost me five thousand euros a day okay so every single day I don't have a solution to that problem 5,000 10,000 15,000 and so it's and this is a hidden cost we don't see the cost of not having the thing okay and this cost of delay is huge it Dwarfs the cost of building things and when I have several things several needs that are unmet all of those things going on at the time the the cost of delay for all of those things starts to balloon okay so waiting for code costs changing code costs going in and maintaining code costs and there's probably the single biggest cost within changing code is figuring out what the hell it does right understanding code costs understanding code that you didn't write sometimes for me understanding code I did write but six months ago me and six months ago means an idiot right I'm super smart now six months ago I was an idiot of course in six months time I'll be saying that six months ago me was an idiot because six months ago me it turns out is always an idiot which is slightly frustrating I mean it either means that I'm learning or I'm not learning one of those is true essentially so code is cost so let's think about understanding code then what does it mean to understand code there's there's three kinds of you can imagine sort of three kinds of code if you like that there's there's code I know because I wrote it okay so I'm pretty confident about that I wrote it recently enough that it's that it's still there and then there's code that's been around stable that everyone knows it's well documented all of that stuff so those two I'm happy minute I'm happy working with code like that I'm happy we kept working with well documented well established code I'm happy working with code that's new enough that I wrote it then there's that awkward code that's kind of code no one knows so it's been around long enough that it got old right but no one noticed it getting old we didn't do anything deliberately about it getting old it just got older and maybe the people who wrote it maybe rotated off the team or maybe they forgot what it did or maybe they couldn't remember the exact reasons why it did it or maybe the reasons are changing anyway maybe it's being used for something it wasn't supposed to be useful but no one really knows and if you look at a sort of volume graph if you like a histogram of that code you tend to find that a huge chunk of code fits in that middle gap okay it's code that's old enough that no one exactly remembers it but not really careful not really nurtured and so my premise then is this code should be stabilized or killed off that's it okay code to be stabilized or killed off fast okay and if we can get into the habit of either stabilizing code or killing code then it means we only end up with code that we wrote recently or code that's really stable and well known it sounds really obvious it's really hard to do deliberately because entropy right because the default state is the stuff just gets older okay I have some disappointing news at the end of this talk everyone in this room will be 50 minutes older sorry can't do anything about that right here's the thing all of the code that you left back at work that's 50 minutes old or two yeah in tomorrow guess how much older it will be yeah so code is aging all the time so one of the things I was doing after I left thought works and went off into this trading firm is collecting patterns of behavior and patterns of software that I felt were enabling these high-performing teams to do really real in astounding things and I got to I spent eight years that thought works had a fantastic time there and I thought I understood all this software delivery stuff and agile and all that and so then I went into this now I come to conferences and talk about it and then I went into this join this very small team and I talked a bit more about them this afternoon but I joined this very small team and and they were doing some really really unusual things and they were the most agile group of people I've ever worked with and they were breaking all the agile rules okay ironic not met but maybe not but so so here's a couple of patterns then and again as I said I'm gonna talk about some more later on today but here's a couple of patterns that I've sort of derived if you like that I observed from this team and that I've seen elsewhere and I've applied elsewhere that helped me reason about stabilizing or killing off code okay so a couple of complementary patterns one is called a short software half-life and the other is fits in my head so I like naming things okay so short software half-life fits in my head so let's take a look at the first one then short software half-life um so half-life of software is a theoretical idea it's a mental model think of so the half-life in physics is essentially this if I have a million atoms of a radioactive isotope depending on what what type of element it is I can know exactly how long it will take for half of those atoms to decay to a more stable State that's called its half-life okay so for each different type of element there's a different half-life and I can measure it and I can know it precisely it's a miserable thing what I don't know is which atoms so I can look at these things a million atoms and and half of them are going to decay in a certain amount of time okay so if I only have a single atom then what happens is after that half-life it's either decayed or it hasn't decayed and in fact it's in this weird state where it's both of those things until I look at it and if you put that in a box with a cat you get a really pissed-off cat and that's most of physics okay so you now all have a physics degree okay you can print them online it's fantastic so I applied this idea to have not putting code in a box with a cat because that's silly but the idea of a half-life 2 software and I'm thinking about this how long and here's a thought experiment to try now think of the code you're currently working on or that you're currently responsible for and think how long would you need to go away for so that when you came back half the code has changed half the code has either been changed beyond recognition you wouldn't recognize it again it's been deleted it's been rewritten it's been it's been changed half of it hasn't but half of it is completely different how long would you need to go away for and I asked this question in might add a class called software faster and I also question in my class and when the first times I ran this class was in Scandinavia and someone was working for a Swedish bank he that morning on his way to class he had been working with some software that was written in 1967 right he he says he reckons the half life of that software is millennia he's fairly confident his grandchildren will be working on that system ok so I write and if we think about half-life of software it's typically I know years right years maybe decades and so I did a back of an envelope calculation with the code we were working with with this trading systems and these are no non-trivial systems and what was happening was the code was just changing under my feet roughly every six weeks I reckon the half-life of the code was available about half of it was different and it was a crazy crazy crazy rate of change but what was happening is these guys were fearless Lidl eating code okay and rewriting code because their premise was by now no more and I can get from public static void main to something that I want faster than I can understand this code manipulate it change it make it do what I want and also the next time I write it it won't have any of these speculative things that I put in I didn't end up using okay so let's think there's some design considerations that are going to enable us to do this so we can't just do that with code you can't take a huge big monolith of like a tightly coupled code and confidently start deleting half of it okay that's not going to fly you're going to get in all kinds of trouble there so I'm going to need some discrete components I'm going to need to build small separate pieces okay because if I have a discrete component I can reason at a component scale and I want to define a component boundary when I define what happens at the edges because then if I can think about what happens at the edges I now own the center and I want to define a component purpose what does that mean that means what is the point of this software and and a lot of people are kind of you know not fans of documenting code code should be self-documenting code self documents what it does well-written cleanly written code tells you what it does it doesn't tell you why it's there okay it doesn't tell you its purpose it tells you it what what it does and the other thing that it doesn't tell you is what isn't there it doesn't tell you all of the design considerations all of the other ways of doing this but I thought through another I don't need those now I'll leave those I'll do it this other way it doesn't show you the three or four iterations it took to get there I mean I can pour over version control history if I want to but when I'm looking at code the code is telling me and it's kind of obvious when you say it out loud the code is telling me what it is it's not telling me what it isn't and it certainly isn't telling me why it is okay so if I don't have somewhere vividly captured the purpose of that component I can't reason about it or at least I can try to infer it by looking at the code I wonder why this is here oh look it seems to do this that must be an important thing there for so I just derived the purpose of that it may not be the purpose of it may be to do something else but when you stand back and squint it looks like it does a different thing okay and finally I want to define its responsibilities responsibilities slightly different for purpose so the purpose is there is is is is what why it's their responsibility is what it owns and and again going back to the boundary therefore what it doesn't own so again if I'm going to replace it if I'm going to change it to be something else I need to know what it's that what it is why it's there what it's responsible for okay once I understand those things I can start to reason about it then also there's a lifecycle element to this so components have a lifecycle in terms of like I I dreamt them up I felt I I decided I needed them I started writing them I introduced them and so now I need to kind of think about how to look after them so in terms of stewardship then I need to write tests and documentation around these things okay when we do the specification by example or programming by example or TDD or whatever you want to call those things those things aren't tests you're not writing tests okay sorry programmers those things aren't tests they're executable specification you can use them to verify some of the behavior of your application that's great that's a side effect okay you haven't got tests for your code yet don't kid yourselves and again documentation to tell me why something's there tell me the decisions that we made mike Nygaard has a lovely blog post and you can find on the googles about architecture decision records ad hours and what he does essentially it's a really simple markdown basically a blog post and in the blog post he says here's the decision we made here's the people who made it here's the things we considered here's the things we discarded the choices we decided not to do and so this is what we ended up with and for extra credit here's some of the risks that our introduces this is the problem it solves but also here's some of the baggage it bring it brings in and that stays in version control so I can look at the decisions that we made over time and so someone who comes into the project since III you're doing this all wrong and you should be using JSON and MongoDB and whatever else and we go okay thanks for your valuable input so here's when we made that decision here's how we made that decision if something has substantive lis changed since we made that decision then then let's have a conversation and they go and they read it they go on in the world wait wait a minute all you thought about all that and you thought about that and you thought about thing I didn't think about and you ended up with okay I'm good with that it's surprisingly effective yeah but also it's there to be challenged what do you know what this has changed since then so let's try an experiment okay let's try an experiment fantastic let's do that so if we're component test commentation if we keep a journal over time of the decisions we make which is different from a wiki a wiki is current state in a lot of places a wiki is just a hipster version of SharePoint Rights where information goes to die but we used to put information in Word documents to go and die now we put it in HTML pages to go and die so this is a blog and it's the blog is searchable one is easy to find things and I want to optimize for replace ability so that means I'm typically going to not introduce libraries that couple components together because if I introduce libraries the couple components together then you know bad things can happen right what it means is okay I'm reducing duplication which is good but now I'm introducing coupling okay which is not great so if I optimize to replace ability I might make different decisions and I should expect to spend time investing in stabilizing right I should expect to spend time if this component is going to be long-lived and it's going to be something that either someone wants to come along and replace and that someone might be me then having some documentation having some tests around it bothering to invest in it becomes useful here's another thing if all my chain and for my code is changing on a frequent basis the information the knowledge about what that code does is in the team right so that means I want to invest in building a stable team that does not mean invest in building a static team static and stable aren't the same thing so a static team never changes okay that's is that the static team gets stale and old and and they lose their they lose their sense of breath if you like they become very kind of echo chamber II a stable team it means I'm very deliberate about onboarding and very deliberate about exiting okay so when someone new joins the team there's a whole process where we bring that new person up to speed when someone leaves the team there's a it's sad it's a sad thing and but we make it a thing right we make sure particularly that if they have any knowledge that no one else has um that we try and capture that knowledge ideally before they leave right so it's not a kind of oh you're leaving in two weeks write down everything you know it's that over time we have invested in in creating that shared understanding so stable teams can move quickly okay stable teams there's a lovely African proverb if you want to go fast travel alone if you want to go far travel together I added a little addendum if you want to go far quickly pack light okay it's not a binary choice it's a scale it's a scale from being completely alone to having a huge army of people and loads loads of stuff you can be somewhere on that scale you can have a smoke a bunch of people that's my shorts off for half life then mm-hmm so my other pattern then is fits in my head so fits in my head this is based on a chap called James Lewis so James Lewis um a number of things well he coined the term micro-services always one of the people who coined the term micro-services I was basically all James's fall but now I work with James that the works and he has my favorite complexity metric okay so and he says he doesn't like to look at code that's bigger than his head so his head's about that big that's about a 24 inch monitor okay so that's about the size of James's head so James Lewis his head I'm proposing should become an SI unit which means we need to chop his head off and put it in a fridge in Paris okay but until we can do that and he seems resistant to this I don't understand it but until we can do this um then I I do you have to imagine James's head it's about a 20 about a screen of code right so this is if this code and of course you know you can muck around with font size as well but let's make it legible so if you if it's more than if he has to page up and down to look at something it's probably too complicated okay so a function or a method or whatever else it might be is there's too much stuff there and so he says okay that means he needs to not I need to make it smaller simpler so it'll fit in his head so fits in my head then obviously it's a metaphor right you don't actually need James Lewis's head nor do you need the 24 inch monitor it's about whether you can reason about something and there's some fairly obvious logic here you can only reason about something that fits in your head right make sense but then the converse of that says this if you can't fit something in your head you can't reason about it and so what we do instead is we have coping mechanisms so one of our coping mechanisms is we divide and conquer so it's a way we do analysis right so analysis for the way I make a big complex design fit in my head is I look at small part of it so if someone says go solve healthcare that's a huge problem as I go solve patient record management that's a big problem go and think about a patient visiting a hospital visiting a doctor at a hospital and think about what that would look like ok yeah I think I can fit men in my head so now I can start to reason about that so what we do with big ugly software systems is rather than simplifying them because that's time and effort and hard is we just we come up with techniques for actively ignoring parts of it so TDD is a fantastic way of actively ignoring stuff that's going on around you yeah or in fact let me let me let me qualify that mocking mocking and stubbing is a fantastic way of actively ignoring things happening around you so where you have where you're writing your tests and they've lots and lots of stubs and mocks what that should be telling you is in order to reason about this piece I have to ignore loads and loads of other stuff which suggests that it's coupled to loads and loads of other stuff which is bad so you can think of mocks of basically pain killers right they're your drugs so the more things I can I'm mocking is easy I've got mocking frameworks that make it easy here you go has at free access to to drug so you don't have to think about painkiller so you don't to think about the pain of the complexity of this system well we should think about the complexity of the system I want to take all the mocks away from all the people and they go oh no look I can't test this thing right so now let's break the system up so that you can but fits in my head occurs along multiple dimensions it occurs along the dimension of Technology so I want technologies that fit in my head some languages fit in your head better than other languages - my favorite examples Clojure and Scala all right so Clojure is a lisp it's basically two parentheses that SMO STUV Scala that right there there you go a little international sign language the Scala okay so for a closure so closure is a very very language it's there's not much to it it's lists and it's so it's called homo iconic which means that that a closure program is written as a closure data structure right - Lisp is you so you have lists and the program itself is a list so you can manipulate code as code is code as data is fantastic and and there's typically one way to do something in closure and it's typically fairly obvious how you do that and and if it's not you look at some of the some of the core libraries and documentation tutorials and and there's a very obvious style scholar least opinionated language I've ever met scarlet doesn't care okay so reusing code so if I'm only reuse code I reads code I say so once I have class-based inheritance yep yep you can have that what about mix-ins yeah yeah we can make sense closures over functions yeah sure don't you like okay thanks what about something as simple as looping right going through a sequence well yeah we've got a for loop yet we got iterator you've got a recursion you've got a functional like Map Reduce taught yeah yeah sure any of the above oh because what that means is this as soon as I have five programmers I have eight dialects of scholar yeah and so that means now which is great it's a great language for the triangles kinds of crazy stuff out just not in my codebase right and so what that means is you as a team need to be a lot more opinionated about those things so we need to say this is our local style it happens at multiple scales so I want to be able to look at any code and that code fits in my head so if we have a consistent style of code I can look at anyone's code and I don't need to think oh this is this is this is Bob's dialect of code so I just need to switch into Bob mode okay although there's some interesting site psychology that suggests that once you do if you have a really high high performing team in everyone knows how everyone else works when you see someone else's dialect of code they have a different style of bug different people carry a foot in introduce different kinds of bugs they miss read things differently and so I know if I'm looking at Bob's style of code it's probably going to yeah there it is routers fix that right but let's not do that so what we it's consistency okay so course multiple scale so I want to be able to look at any class and it looks like I wrote it or it looks like anyone in the team wrote it and I pan back and I look at a component that component fits in my head and I can look at the way that a bunch of different components talk to each other and they all answer my phone started ringing um a bunch of different components talking to each other and they all talk to each other in a consistent way so that fits in my head I can reason about a system and if it's done if we build something consistently I can something I learn over here I can apply over here and that reduces my cognitive load it makes it easier for me to reason about things and when we start getting slightly larger they start scaling um what happens is you have a bunch of different teams and all the agile stuff tells you that the team is the unit of delivery and teams are autonomous and teams should make their own decisions and in Systems Theory terms we call that local optimization and local optimization is fatal for any kind of global delivery okay any kind of global optimization of a system will will be sabotage by local optimization and one of my favorite examples of local optimization is when you see the slide that goes up this is these are some of the technologies we use we've seen one going Cassandra and HBase and then there's 15 different things up there and they're going to look at us we're little we're this cool and I'm like you're not the operations team are you you're not downstream of all of those crazy decisions are you you're not the person installing upgrading securing monitoring administering are you no no of course not because otherwise you probably be making that much much much smaller set of sensible choices okay and so um there's a couple of ways we can do this one is ah I can say right so James again James has to be in all the meetings that's a good way to get consistency that'll work um well yeah except that a it sucks to be James and B that means that James is now a massive bottleneck okay so that's a problem so so instead what we could do is this is we could all wear a little badge it says what would James do and we're in a meeting we say okay I need to make this decision about persistence or about monitoring whatever it is what would James do and that means that we're like they're not actually James you know but what you've done is you've created some shared values some shared guidelines so you can all make consistent decisions and the thing to do then is to check in with each other we decided this thing we're thinking about doing this thing what do you guys think well that makes sense because we're doing this thing and that's kind of aligned or well we're doing a different thing over here let's have a conversation about that and figure out what the most sensible thing to do is and then you can start to scale contextual consistency then and so I want to agree these guiding principles agree idioms agree how we're going to do things around here and at that point difference is data so that means if I see something that's not like the other things that's probably signal that something interesting is going on here okay and in particular the idea that familiarity is not the same as simplicity so what does that mean that means things that I'm used to seeing that doesn't necessarily make them good ideas it just makes some ideas that I've seen a bunch of times okay so we get the boiling frog syndrome so you put a blob of frog in cold water and you gradually heat the water and the Frog Bulls death you know that's not true if you heat up a bowl a bowl of water with a frog in it the Frog goes wet it's getting a bit warm in here and jumps out okay however we all think it's true because we've all heard the story and that is boiling frog syndrome so a little bit metaphor okay we all think a thing that we heard is true so I need to move on because I'm running out of time and I'm not well actually as she knows he's going quite well I thought I had a ton more stuff to get in and I just just landed on the bit that I want to tell you about microservices there again so oh yes I'm not calling the micro services I'm calling it a replaceable component architecture and this is what I mean by an architectural style okay any architectural style which has components which are replaceable okay this creates options for me it means I can reason about code differently okay there are many many replaceable component architectures so what does a replaceable command architecture mean it means I start with now is that this is how I achieve my sustainably okay this is how how I start building my my sustainably reducing lead time okay if I if I keep things replaceable and I keep things componentized it means I can reason about them so there's my component there you go took me ages to draw that okay here's another one okay so this is this is my component diagram I guess have some all right so these are components okay each component does a thing but remember each component has a hard shell okay it's wrapped in it it's wrapped in a hard shell and these components they talk to each other they send messages to each other okay so they're like little computers passing messages okay um I'm not the first person to use the phrase little computers passing messages does anyone know who was the person who said little computers passing messages no one Allen case is one person well done so this is the man who coined the term object-oriented programming um and he said object-oriented programming said objects are little computers passing messages and he recently a few years ago on a mail list he said them my biggest regret with oo is I didn't call it message oriented programming because the objects were a complete red herring he said really it's all about passing messages we as an industry massively messed up oh oh okay and I still hear quite you know people who I regard as a fantastic software people talking about hello and they still talk about you know these objects have be modeling objects in our world and those are the objects they're not no they're not no they're not an object-oriented system doesn't model objects in your world that's not what objects are objects are little computers they're things that do stuff so the objects in your world are called entities they've always been called entities they're called entities in in relational model they're called entities and databases they're called entities and object oriented they're called entities in domain modeling right in the main driven design they're entities they're things they have state and they have identity okay so an object in oo does things with entities and pretty much anything interesting requires using multiple entities so for instance if I'm moving money between accounts that's I'd have an object that does that and have a transacting a money transfer object so really the things we think of as services verbs verb phrases those things are objects they're little computers and what they do is little computers pass messages to each other okay so he was talking figuratively this is back in the 80s yeah we now literally have little computers pass image you saw some there was a little pile of little computers here right if you're in the Kuban eaters session okay literally little computer so he couldn't have imagined that way maybe hit it right but we've got literally little computers fighting messages that's way cool okay talent case is this and um yeah and so now I can reason about a component purely by thinking about it in terms of the messages it produces and consumes right and so that means I can test a component purely in terms of the messages it produces and consumes which is kind of cool because that means that now unit testing functional testing integration testing all of those kinds of testing all collapse into the same space which is testing okay and replacing one of those components I replace the green bit I replace the innards I leave the hardshell so the API defines exactly my contract with the world and again that's kind of useful so microservices can be a replaceable component architecture they're not necessarily and a lot of the places I see them they're not okay my beef with the term micro-services is this is micro-services suggests smaller is better micro are microsomes i've got this one line service right so you look at the proliferation of tiny little javascript libraries and there was that wonderful thing recently where someone removed a JavaScript library that pads spaces onto the left side of a string apparently these days we need a library to add spaces to the left side of a string oh my word because what is far more complicated to write some code to add to figure out how many spaces I need to add than to add a dependency at a dependency management tool download the dependency pull down the internet the dependency pull it depends on and then realize that that dependency package requires another dependency package to function as a dependency installer I wanted to add the stupid spaces right but so we can we can we can go too far with the micro so micro services can be a replaceable component architecture if I choose to optimize for replace ability and consistency if those are the things that I care about if those are the things I value I can get to a replaceable component architecture it means that I can reason about each of these micro services what does it do what's its responsibility what's its boundary and what's its purpose once I understand the purpose of that thing I could replace it with a different thing and I know that that I can do that confidently and once we can start doing that that creates options for change ability that creates options for agility okay smaller isn't necessarily better we don't want littler services we want replaceable services so we're more replaceable unfortunately replace a blur isn't a word I'd like it to be a word more replaceable is better okay so my message to you then my plea to you my request to you is this kill code fearlessly okay so remember we've got the code I know we've got the code everyone knows I've got the code no one knows yeah so if we can confidently kill that code that means we're in a position where we can move quickly right where we can iterate quickly where we can respond to business need quickly which is business agility okay remember we're trying to minimize lead time to business impact so that's all I had thank you you
Info
Channel: GOTO Conferences
Views: 27,736
Rating: 4.861804 out of 5
Keywords: GOTO, GOTOcon, GOTO Conference, GOTO (Software Conference), GOTOams, GOTO Amsterdam, Dan North, Post-Agile, Agile, Computer Science, Videos for Developers, Software Industry, Software Developement, Software Engineering, Lean Agile, Microservices
Id: 4Y0tOi7QWqM
Channel Id: undefined
Length: 37min 21sec (2241 seconds)
Published: Tue Sep 27 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.