On November 18th, we had the incredible opportunity to talk with Trisha Gee, Java Champion, and leader of the Java Developer Advocacy team at JetBrains, and Kevlin Henney, thought provoker at Curbralan, about the new book they edited, 97 Things Every [Java] Programmer Should Know.
The book is made up of 97 chapters written by 73 contributors. And, although there are many more things a Java programmer should know, this book draws on some of those many perspectives to collect a cross-section and representation of the thinking in the Java-verse.
Here are some highlights of what went on:
Codecamp: The book is a testimony of the fact that things get more complicated over time. When we started out, many years ago, people wiser than us told us that we should pay attention to two things: naming convention, cache invalidation, and off-by-one errors. Now there are 97 things we should pay attention to! What we like most about the book is the fact that one can open it randomly and get an interesting fact or learn something. That and the fact that most of the 97 things are written by past Codecamp speakers.
That being said, our first question would be what is behind the title (97 Things Every [Java] Programmer Should Know):
Kevlin: I’ll take this one, seeing as how I was there in the origin story, which happened in a land far far away from now, in the 2000’s. Bruce Eckel, who wrote Thinking in Java, ran this private chat for various people and we just used to have discussions there. And one of these people was Richard Monson-Haefel who asked Well, what are the things that a Software Architect should know because I’ve submitted this talk, called 10 Things a Software Architect Should know, and now I need 10 things! So, what are your suggestions? And he got a lot more than 10 suggestions. He said Well, this is really interesting, we could actually make a book out of this! He knew somebody at O’Reilly, but we needed a lot more than 10, about 100, but 100 is too obvious, and 101 and 99 are trying too hard not to be 100, and that is how we came up with 97. It has a nice feel to it. So, the first book was 97 things every Software Architect should know, then we had a series of books which I edited, and the whole series is named 97 Things. And then, we thought, let’s get language-specific, and that is how we ended up with 97 Things every Java programmer should know.
Codecamp: Let’s talk a bit about the first topic in the book: All you need is Java!
Trisha: I thought this was an interesting approach because it was trying to get us to think less than all the libraries and frameworks and all the rest of it out there. We can do quite a lot with the Java libraries that come with just the JDK. A couple of years ago, when Java 9 came out, I tried to create a microservices application with just the JDK and no additional frameworks and libraries, and I did manage to do that. I don’t recommend it, because you have to hand-grow an awful lot of stuff which other people have done already. But there is a lot of stuff in just Java which gives it a lot of power and a lot of flexibility.
Kevlin: Anders Noras wrote that piece and it is exactly like Trisha said. I think a lot of people, particularly as languages grow and this is not unique to the Java space, a lot of people will start a new development, not even asking the question of what we are trying to build, but by saying what technology stack we shall use. They bring in a lot more complexity than they need. You’d be surprised what you can do if you take it back a little. Sometimes people reach too quickly for dependencies when actually they already have what they need, either in the language or in the immediate realms of the JDK Libraries. Sometimes we forget what’s there.
Codecamp: Let’s jump to number 54 in the book: Learn your IDE to reduce Cognitive load.
Trisha: Just to set the scene, I do work for JetBrains, and I am a Developer Advocate for IntelliJ IDEA. So, I was thinking, how can I write something about how IDEs are amazing, without it being all marketing for IntelliJ IDEA specifically. So, I was thinking about why do I like to use IntelliJ IDEA as my IDE vs coding in any other way. Because I have used other IDEs, I have coded using compilers and such. So why is it that IntelliJ IDEA specifically helps me as a developer? And it is mostly because it stops me from having to think about other stuff. It reduces my cognitive load. Instead of me thinking what an if statement looks like, how do I type that, you just type it, or if, and IntelliJ IDEA just fills out with a live template, and it just writes half the code for you. A lot of people argue that that is lazy. Well, yes. But laziness is not necessarily a bad thing from a programmer’s point of view. You want the tools to do the boring, easy, lazy stuff so that you are thinking about what the business problem you want to solve is, what do you want to deliver, instead of thinking how do I write an if statement, how do I migrate this code from one thing to another, how do I extract a method. So instead of having to make all these steps, thinking about my lines of code, I just say to IntelliJ IDEA refactor this method and extract this thing, and run all my tests so that I can prove everything works and that’s it. So, by all means, think of IDEs as something that is going to make us lazier but that just frees up our minds to think about more valuable stuff for the business.
There is a cost to it, because, in order to reduce your cognitive load, you have to invest time, to begin with, to learn these tools, and that’s why sometimes it is difficult to switch from tool to tool. And if you are going to switch languages, you might not have the time, or you might not feel like it is worth the time investment to learn the specifics of one tool for one language for one small project. So everything has costs and benefits.
Codecamp: What about number 66? Program with GUTs. Kevlin, this is your right?
Kevlin: Yes, this is mine. And GUTs is an abbreviation that Alistair Cockburn came up with a number of years ago: Good Unit Tests. These days we talk a lot about testing. We have done for a while now, the conversation has increased, I am fortunately or unfortunately old enough to remember when unit testing wasn’t really a thing that developers did. I am not saying that all developers now do it, sadly no testing is still the most popular testing technique, but in terms of number of developers that are much more focused and interested in their craft nowadays, the number is way higher. The discussion is if we have unit tests, that must be good automatically. Well, no, it is a bit like code. You can have code that works against you. You can have code with unmanaged technical debt. You can have the same experiences with tests. People often forget that we treat tests as second-class citizens because tests don’t go into production. But it is part of the pipeline, and somebody has to maintain it. And I’ve seen many cases where people’s hearts are in the right place, but it all comes back to this investment in technique as with anything. What makes a good unit test? What does a good unit test look like and what would you be comfortable maintaining? What would you be comfortable coming back to later? If something failed, what would you expect to see? It all comes down to whether you are just trying to test if the code works or are you showing me what you mean by the phrase “it works”. Because that’s the hard thing. Let’s say you join a new project tomorrow morning, you wouldn’t walk in there and go, hey does your code work? Normally your question would be What do you mean by it works. That is the hard bit. What does it actually mean? Sure, it goes green, but what does that actually mean? So good unit tests have a strong role in communicating meaning, they should be readable. Some of the things that make a good unit test readable are not the same as what makes production code readable, it has its own conventions.
Trisha: I quite often look at unit tests when I first look at a code, especially when I don’t know what it does. I don’t look at the tests just to tell me it works. I look at the tests to sort of figure out the thought process of the developer is, particularly if it is logically related. I kind of expect the test names and the way they are set up to explain to me as a developer, why those choices were made when the production code was written. But, as you said in the article Kevlin, if you have something that says just Test 1, you can’t get much out of it.
Kevlin: Yeah, I’ve seen those tests: Test 1, Test 2, Test 3…and I’ve asked those teams, well what does it mean when Test 3 fails, and they just shrug their shoulders. So, what does it mean when it passes? We are stuck with the same question. Testing should be an active communication. It is an act of explanation; you’re trying to get inside the mental model so that it tells you a little bit about the why. It is a really good way of showing how well your code is encapsulated. But unlike comments, they get executed. If it goes to green in one build, to red in another, you are moved to do something about it, whereas comments just disappear into the ether.
We also addressed several other topics with Kevlin and Trisha, ranging from fundamental OOP principles that are sometimes ignored (Behaviour is “Easy”; State is Hard), what should go in a constructor (Minimal Constructors), up to Building Diverse Teams or Embracing SQL Thinking. If you want to find out more, watch the entire Codecamp_Talk on our YouTube Channel.
And, if you are curious about all the 97 Things a Java programmer should know, you can order the book here.