- Hi, I want to make sure that you fully understand
what this material is and where it's coming from.
This is why I truly hope you start these lessons
right here with Prepare Your Mind.
Follow these lessons in this first section,
because it's really gonna help prepare you
for not just the material we're gonna teach,
but how I'm teaching it,
and why I'm teaching it the way it is.
Now you know, somewhere along the line,
we came up with this idea that programs and projects,
large amounts of codes were really, really cool.
They were awesome.
But I want you to understand
that this is not really where we want to go today.
We're gonna learn that lines of code
really can affect how healthy a project is,
how healthy a team is.
And I want to start moving away from being oppressed
with projects with large amounts of code.
If you look at the Linux operating system
as an open-source project,
there's about 24 million lines of code
in that project today.
That is immense; it's massive.
It's gonna take a massive team to be able to deal with that,
and I personally don't want to be on projects like that.
Now here's another thing that I want us to focus on
and understand that Go is trying to solve.
We were taught to create these large abstractions
in our code base to deal with change.
In fact, we've been taught
to put abstractions on top of abstractions.
This is something that we also need to get rid of,
because all this is doing is adding more code
to our project, which is gonna be causing more pain.
I think one of the most beautiful things about Go
is that we're gonna learn how we can create
these very thin layers of decoupling
and still achieve our ability to deal with change
without all these extra generic layers of abstraction.
Now here's another one that a lot of people lose,
and it's not fair.
The languages you may have been using
could have been using a VM, like Java and C Sharp,
where there's a virtual machine there
taking care of what we will call mechanical sympathy.
We're gonna learn mechanical sympathy in this class.
But what's important here is this,
is that if performance matters, and it does,
that's why we're here using Go,
then it's the hardware that matters,
because it is the hardware that executes instructions.
Your performance is gonna come
from the hardware, nothing else.
So we either need to be sympathetic
with the hardware or not.
The hardware is the platform at the end of the day,
if performance matters, and we all know that it does.
And the last thing here,
and again, I think it's lost
because of the languages that we've been working with,
is that engineering is about understanding cost.
Every decision you make comes with a cost.
There's a benefit for that decision and a cost,
and if the benefit is not outweighing the cost,
you shouldn't be taking the decision,
shouldn't be making that decision.
So part of this class, a big part of this class
is understanding that engineering
is about understanding the costs you are taking.
And when you don't, you're not coding,
you're not engineering.
You're hacking, and we can't have that today at all.
Now another thing that's very important,
these are things that I believe Go is trying to solve.
These are problems that Go has seen,
and we're trying to solve them with Go.
And this other one is that the idea is
that you cannot throw more hardware at the problem.
Now not many of us have data centers anymore.
We're using the cloud.
And so I can apply that to the idea
that you can't through more cloud computing
at the problem anymore.
It's expensive stuff.
So one of the big things about Go
is we're trying to write software
that minimizes the use of resources,
minimizes the use of that hardware,
minimizing the use of cloud.
Why?
We'll keep those costs down.
We're on shared machines,
making all these things that are gonna tie back in together
into the language as we continue to learn it.
And we already know that you can't throw
more developers at a problem.
At least historically it hasn't been the case.
How many times have you been on a team,
and a manager, somebody in management
comes and says, "well, you know,
"if I throw another developer on this project,
"could we get it done faster?"
And I'm always like, look, this isn't accounting.
It's not like I can throw an accountant on here
and we're gonna move faster.
This is software development,
and there are things that cause us
to have pain as a team grows.
I think Go is solving a lot of these problems
also around package-oriented design.
We're gonna talk about these things.
And there are ways to structure,
package projects together
where we could put more projects,
developers on a team and potentially get more work done.
But we have to know and think about this up front,
and the language has kind of done that.
So throughout this class, throughout this class,
throughout the 15 hours that we're gonna be together here,
I need you to always be a champion
for quality, efficiency, and simplicity.
I'm gonna try to teach you how to do that.
It's critically important
that you always have a point of view
and self-reflect about who you are as a developer.
But I don't want you to hold back on your point of view.
I want you to analyze and self-reflect.
What is my philosophy here?
What is driving the engineering decisions that I'm making?
Am I improving as a developer?
It usually means that you're improving your point of view,
that it's changing.
It's okay to change your mind on something.
That's growth, and we want to have that all the time.
So as we continue to focus on this class,
I want you to open up your mind.
Look, technology is changing quickly.
We feel it and see it every day.
But our minds change slowly.
We resist to change.
And it's always easy to adopt new technology,
but it's hard to adopt a new way of thinking.
And one of the things I've gotta do in this class
is kind of break you down and build you back up.
There are things that I'm gonna be asking you not to do
that you've been doing historically or been taught to do.
Go has different costs for things,
and that means that you've got to make different decisions.
And it's not that what you were doing before was wrong.
It's just that it's not necessarily the best
or the right thing to do when we are coding in Go.
And these are things that I'm gonna try to teach you
over the time that we're gonna spend together in this class.
Now as we continue to talk about this,
I want to focus on this idea of legacy software.
If you ever met me in a bar
and I've been drinking a little whiskey,
and you happen to tell me that you're a software developer,
well, one of the very first things I'm gonna ask you
is what is the legacy you're leaving behind?
This is a critical, critical question
that you should be asking yourself.
Now I've got some really great historical quotes here.
I think history is critically important,
mechanics after that, and semantic behavior.
We're gonna talk about all of these things
throughout the class.
But I love this quote from Peter.
"There are two kinds of software projects,
"those that fail and those that turn into legacy horrors."
This is great.
Every time I say it, I crack up a little bit.
But it's so true, right?
What is a project that fails?
A project that fails is a project
that never makes it into production.
But a project that gets into production
and is no longer able to be maintained,
that's a legacy horror.
And if you really think about it,
we've got 40 years of software
in this country, around the world,
that is really a legacy nightmare.
It is.
I can't tell you how many times
I walk down the street
and just wait for the lights to turn off.
I'm always saying that I don't want Hollywood anymore
to write movies about earthquakes and asteroids.
I want a movie about legacy software
systematically failing all over the planet
and no one being able to do anything about it,
because there aren't any Unitests to deal with it.
And I've got clients today, today
that are writing legacy code out of the box,
mainly because, one, they don't know
how to do it any other way,
and two, they create
these incredibly short-term milestones for themselves
which just really can't be met.
And at the end of the day, all they're doing is hacking.
Look, Chuck Moore said it best,
"legacy software is an unappreciated but serious problem.
It is gonna "be the downfall of our civilization."
I really believe that.
But we today have opportunities to learn
how to write software that isn't legacy out of the box.
Go is at the forefront of this.
We've just got to learn how to rethink
how we do software development,
restructure our software development,
and keep this in the front of our minds at all time.
But I think one of my favorite quotes
throughout this entire class in all the material
comes from Sarah Mei.
If you don't know Sarah Mei, you need to look her up.
She is a powerhouse, a thought leader in our industry.
And though she spends most of her time coding in Ruby,
I don't care.
What she talks about,
and the things that she tells us
applies to almost any engineering
that we're doing in software development.
And she said this, and I love this quote.
"We think awful code is written by awful devs.
"But in reality, it's written by reasonable devs
"in awful circumstances."
And I want us to understand that,
because all of us at some point
are gonna be asked to look at a piece of code
that we haven't written.
And when we look at that code,
we might come up with a conclusion
that I don't know what kind of drugs
this developer was on,
but they should have been sharing them,
because this is out of control.
But I want us to step back and think,
and say, whoa, whoa, whoa, whoa, whoa.
Let's not trash the developer who wrote this piece of code.
Let's come back and ask ourselves,
what was the condition or situation they were in
when they had to write this piece of software?
And now we're here to maintain it,
and maybe we can even improve it.
And so I want us to all have empathy
for everything that we're doing,
because every environment is different.
Every situation is different.
And we're going to be asked
also to maintain code that exists.
But as you continue to write new code,
I want you to think about that person
that has to maintain that code after you.
That's going to help us move away
from these legacy issues.
Sarah Mei, brilliant quote.
Now if we really are gonna focus
around not creating legacy code out of the box,
for me the number one thing,
the number one thing we have to keep in mind
are mental models of the code base.
Mental models are everything.
And it's gonna be part
of your daily refactoring of the code.
Mental models, number one.
Now Tom Love was the inventor of Objective C,
who said this.
And Tom Love works for the Department of Defense
on very, very, very large projects.
But he said that, "let's imagine a project
"that's gonna end up with a million lines of code or more.
"The probability of that project being successful
"at least in the United States is about 50%."
This is a nasty thought that once projects
get over a million lines of code,
they're probably going to fail.
This is scary.
But why is Tom saying this?
He's saying it because he identified that
a ream of copy paper is about 10,000 lines of code.
Now put that in your head.
I mean, we can all imagine
what a ream of copy paper looks like.
I'm sure we've all touched a ream
at one point of time in our lives.
That's 10,000 lines of code.
What Tom is saying is that a developer,
the average developer really can't maintain
a mental model of code beyond that 10,000.
When we talk about maintaining a mental model,
I don't mean memorizing every line of code.
What we mean is that you know
where everything in that code is.
If I ask you where this function is,
if I ask you where certain things are,
you can find it quickly.
You know how the flows work.
You know how variables are named.
You understand the code base intimately enough
where if there is a problem,
you can probably go to the code,
identify where to start looking,
and start reading that code very, very quickly.
That's the mental model.
This is what we're looking for.
And Go is going to allow us to do this,
because we're gonna be able to write less code.
But this is really what happens.
If the average developer
can only handle 10,000 lines of code,
then once a project goes beyond 10,000 lines of code,
you need a new developer on that project.
And when we start talking about code bases
with a million lines of code,
we're talking about 100 developers on that project
if we really want to maintain our mental models
and the health of the project.
And I don't know about you,
but historically I've only ever worked on teams
of about three or four people.
And I can tell you, it is difficult
to keep three or four people rowing the boat
in the same direction every day.
Imagine trying to do that with 100 people.
This is why these projects fail.
As the larger the code base gets,
it's not even so much a technical issue anymore
beyond the fact that you have to manage more people.
You have to maintain these mental models.
You probably don't have even one person
that knows the full mental model of that code base.
It really becomes both a technical and a management issue.
So we really want to focus on lines of code
and reduce it and to identify the health of our teams.
We really need to understand is there,
that 10,000 to one developer balance.
Now cognitive load is really, really important.
Brian Kernighan said this best,
"the hardest bugs are those
"where your mental model of the situation is just wrong,
"because you can't see the problem at all."
And everybody knows that debugging a program
is twice as hard as writing it,
so if you're clever when you write it,
how are you gonna debug it?
People find this really interesting,
but historically I've been writing software for 30 years.
Historically, I never allowed developers on my team
to use a debugger without asking for permission.
This is primarily because when there is
a problem in production,
all you have is your mental model of the code base
and the logs that you're writing.
But if these are not helping you find bugs,
you're done, you're lost.
You're not gonna hook your debugger
up into your production environment.
And I'm not saying that debuggers are necessarily bad.
They are a tool.
But they shouldn't be your first tool to finding the bugs.
They're great if you've got a brand-new code base
and you want to understand how it flows,
but I have a 20 minute rule,
and that 20 minute rule would say
leverage your mental model,
leverage your logging to find that bug.
And if you can't after that, we'll turn it on.
But we've got a refactoring problem
in front of us at this point,
because we've lost it, right?
So I don't want us becoming attached to debuggers.
I want us to focus on our mental models
and really also making sure that we create logs
that have more signal to noise.
Because I love this quote,
"debuggers don't remove bugs."
They really don't.
"They just show them in slow motion."
At the end of the day,
we've got to refactor that code cleanly
so those bugs disappear.
But at the same time, if more bugs start to show,
I don't need to waste time on the debugger.
Our mental models, our logging, it all helps.