QR code

Shift-M/53

  • Moscow, Russia
  • comments

@yegor256 · Shift-M/53: Adam Tornhill on auto-detecting technical debt hotspots

Adam is a creator of CodeScene, a cloud service where you can check the quality of your code and spot places where your technical debt is the largest. He’s also the author of “Your Code as a Crime Scene” book.

Adam’s personal website

His Twitter

The book: Your Code as a Crime Scene

Video is here.

Transcript

[00.00.00] Yegor: Shift-M podcast, welcome everybody. We have a special guest today, Adam Tornhill. Adam is a software developer, definitely a book writer, founder of a platform which analyzes the quality of source code repositories. And which is the most interesting, in my opinion, for us now for the discussion, Adam is the author of a concept for the idea of how source code can be analyzed and represented graphically in order to enable better decisions about further improvements or refactor. That’s what I understand. That’s what I understand from your blog and from a number of your presentations, which I’ve heard. So, Adam, can you tell us briefly what it, whether I’m right or wrong and what this method is about.

[00.00.52] Adam: Yeah, sure. I’m happy to do that. So, I’ve been calling the concept of behavioral code analysis and basically the challenge I tried to address was that all the static analysis tools I’ve been using in the past were pretty good at kind of detecting issues, they were pretty good as a low-level feedback loop when writing code, but they weren’t particular good at prioritizing the findings if you apply them to a larger system. So, what I decided to do was instead of starting from the perspective of the source code, I started from a perspective of the humans, the people writing the code, the developers. So basically, tapped into virtual controls to find patterns in how we, as developers, interact with the code we’re building. And I kind of use that to deduce a bunch of interesting information, for example, identifying what I call hotspots, parts of the code that are being worked on the most. I can also identify things like implicit dependencies that aren’t visible in the source code itself that can further inform us about their architecture. And finally, I applied a bunch of visualizations, heavily inspired by forensic psychology to kind of be able to communicate around something as abstract as source code with non-technical stakeholders. So that’s the very short version.

[00.02.04] Yegor: So I created an account in your system a few days ago, and I played a little bit with this analysis mechanism, which analyzed my source code base, and it gave me this small and large circles for certain parts of the code, which was very interesting for me as a software developer, but I’m questioning myself whether this information will help the managers, the people who make the decisions about resource allocation in software team to actually make better decisions. Will they pay attention to that?

[00.02.37] Adam: So, my experience is that, yes, I think we get there. We might not be 100% there yet, but I think it’s one of the most important things we can do in the software business to make a code quality or business concern, because the code quality is going to constrain us as a business, what we can do with our system, how we can evolve our own business. So, my experience is that our manager or non-technical manager won’t necessarily understand the information out of the box the way it is today. But if you sit down with them and you explain to them what it actually means in financial terms, then they do get it and they start to pay attention to it. So, I’ve been fortunate to work with lots of companies around the globe over the past five, six years. And my experience is that once they understand it, they do embrace it and they tend to use it totally for things like planning and prioritizing.

[00.03.31] Yegor: So, they basically get back to the software team and they say, “I understand where the riskiest part of the code and I would like you guys to focus that in the next sprint.”

[00.03.43] Adam: Yeah, that could be one example because one thing I’ve observed over and over again, I know this is also supported by the technical debt research community is that so many developers and development teams are forced within quotation marks to take on technical debt. So, if you don’t really understand source code, it’s where we were easy to make this trade off and say, “Hey, let’s get this feature in.” We don’t really care about maintainability. And what happens is that software developers’ kind of lack a vocabulary to explain the consequences to managers. I think the technical debt metaphor doesn’t really work there. And so, what I kind of like to do now is to also kind of empower software developer so that we can have this conversation with management and say, yeah, sure, we can do this, but look the code, all of this code is spread, right? It’s already a mess, and if we squeezed this feature in, we’re going to put the sustainability of code base at risk. So that’s the situation I would like to get to.

[00.04.45] Yegor: You know, in most cases, and I can confirm that being a software developer, programmers actually are scared of demonstrating, of revealing this information to their managers, because the first question would be how come you claim to be a good programmers and your code all of a sudden is in red. So, what’s going on?

[00.05.09] Adam: Yeah, yeah, yeah, that can definitely happen. And I think one issue is that there are so many, there it’s not only the source code it’s on also about the whole organizational side of software. Right? But I kind like to think that the reason we end up in situations like that is because we simply lack visibility into software, and we lack visibility for a long, long time. So once the problems become too obvious, it’s already a mess. That’s going to be extremely expensive to sort out. So, I think it’s a very delayed feedback loop there.

[00.05.45] Yegor: In one of your presentations, you said that in one project you detected, if I remember correctly, 4,000 years of a technical debt, that’s sounds like a scary number, but can you explain what it means. 4,000 years of technical debt?

[00.06.00] Adam: Yeah, yeah, yeah, exactly. That’s yeah, that’s one story I shared. It was actually one of my first clients when I started CodeScene. So, when we’re early on, I often supported my client hands-on with getting started, which was a good learning opportunity for me as well. And this team, they had used our static analysis tool prior to my arrival and thrown it at our 15-year-old code base, right? And this tool simply reported that, hey, look, you have 4,000 years of technical debt on this 50-year-old code base. And it sounds absolutely crazy, but of course a lot of that debt, grew in parallel. And in fact, a lot of it isn’t really technical debt because a static analysis tool can never measure technical debt, what it can do is it can measure the remediation cost, the cost to fix it. So that’s basically how these tools work, they kind of scan the code base to find some construct that violates some of their rules, and then they have a number associated with that, that refactoring this will cost you two hours. So now we have two hours of technical debt continue to scan, find something else, public metaphor for that lacks documentation or whatever, takes you five minutes to fix you sum it up two hours and five minutes of technical debt. So that’s basically how it works. The issue I had with it is that even if that number is kind of accurate, it’s not really accurate, right? It’s depressing, but it’s not really helpful because what we’re lacking is kind of the priorities on top of that.

[00.07.22] Yegor: And what do you think a team or managers of the team can do when they hear such a number, 4,000 years? What’s the next step, where to start?

[00.07.34] Adam: Oh, that’s where we’re tough and becomes dangerous. So, in my experience, what many teams do in that case, or many managers is that they put some quantitative goal on it. So, they say things like, all right, we have four, five years of technical debt, the first thing that happens is that everything that’s categorized as an improvement, or just a warning that kind of goes out of the window, we throw that away then you focus on the major issues, and you might have like 7,000 major issues. And then you put the quantitative goal on it and say that, okay, let’s bring it down from 7,000 to 5,000. And we know when I hear something like that, I can always advise against it because I think first of all, it’s dangerous with the quantitative goal like that because it completely lacks a connection to the actual business. Right? So, I think the only way to kind of prioritize those issues is based on the business impact. Many of them might not even have to be fixed. Others are critical to fix now.

[00.08.35] Yegor: It seems to me that prevention of a technical debt growth, is way more important than fixing it later.

[00.08.44] Adam: Yeah. Yeah, I absolutely agree. And there is this wonderful research paper that I quoted it in software design x-rays that actually looked at the, when is technical duct introduced. Because I, for a long, long time, I kind of just assumed that, you know, when we write code, the first piece of code we write is always beautiful, right? And then at some point it kind of starts to degrade, it gets a bit worse. But that’s not really what happens with technical debt. What this piece of research showed was that most technical debt is actually introduced in a very first iteration on a module or a file. So, kind of anything we can do to prevent that from getting in, is I think vital. Because once we have technical debt, it’s always expensive to pay it down. And it’s always that conflict with what we want to do with the product.

[00.09.33] Yegor: And to prevent that, we do what? We do, style checking, static analysis? How do we prevent the debts to grow in a code base?

[00.09.44] Adam: It’s always multiple things. I’m personal. I’m a big fan of automating as much as we can. So, what we do ourselves at CodeScene, because we kind of, we always been eating our own dog food, right? So, we have codes in as a quality gate. So that’s the first thing. So, if any code declines in quality, then we kind of stop the build and we have to fix it. But it also goes to things like, I like peer reviews. I’m not a big fan of style checkers. And, but I do like peer reviews, because it’s also a good way of kind of ensuring that what we do is on track with the style we want to have on the project. And then also think it’s one of the most important components is of course the skills of the team, right? So, if you don’t have it, it’s going to be challenging anyway. So having really, really good developers, definitely helps because those people are aware of all these pitfalls.

[00.10.39] Yegor: You’re saying you don’t, you’re not a fan of style checkers, but how do you measure objectively the size of this debt? I mean, looking at the source code, let’s say the Java file with the Java class, or, you know, whatever your list class, you have to, your tool has to tell us, what is wrong with this file. And in order to do that, you need to have metrics, not people subjectively looking at the file, you have to have some instrument which will objectively tell you, okay, the quality of this file is 5.3, and another file is 7.2. So, what if not style checking? How else we can measure that quality?

[00.11.23] Adam: So, I always try to separate, I think static analysis is very valuable, right? So, but there’s a subset of it that I find value in personally, and that value is the things that actually impacts our ability as humans to understand source code. And those are things like, you know, deeply nested logic, for example, this will be software friendly, or software maintainer. But then there are other more stylistic issues, like where do you place your curly braces? Does every public method have a comment, stuff like that, that I think don’t make up good general rules? Of course, consistency, it’s, I mean, it’s always a good thing, right? But it’s not that important in my experience. Does that help in clarifying what I meant?

[00.12.11] Yegor: It does. And again, one of your presentations you mentioned that, a number of really objective metrics and a few of them, I really like very much, for example, this bumpy road metric or code smell type, which you suggested, it seems to me a little bit controversial because I always thought that the code which is written in a more hierarchical and nested style, is better than the code which is more imperative and directive where instructions go one by one, but it seems that this metric is quite opposite. So can you explain how it works, this bumpy road code smell.

[00.12.56] Adam: Yeah. Yeah, sure. I’ll be happy to do that. So, the inspiration from that actually came from a research paper. A lot of the things I do with codes, and I try as far as possible, I try to base it on actual research because I think that one issue with the software industries, that we have so many opinions and there not enough facts. So, I try to do my best. And, what I found out was that there was this brilliant research done by Ericson on their large telecom systems. When I found out that one of the best predictors of software effects were actually deeply nested logic, you know, if statements, instead of statements. So, I start to look into that, and then I kind of did this observation that some function, some efforts that had multiple chunks of deeply nested logic in its implementation, were more defect prone. And I course simply call that code a smell bumpy road because it kind of looks like, you know, you’re driving on a bumpy road, it will just like it slows down your driving, it will slow your down, your code rating speed, and your ability to comprehend a code. And I also like to think that it’s a worse code smell and just feel it nested logic because each one of these chunks of nested logic that make up the bumpy road, they kind of suggest a separate responsibility. So why not extract them put a name on them, because as a psychologist, I know that, you know, putting a name on things, it’s one of the best things we can do to kind of optimize our working memory.

[00.14.29] Yegor: So, you were suggesting that the code has to be as close to the left border of the screen as possible?

[00.14.37] Adam: As a general recommendation, yes, there are always tons of exceptions of course, but yes, I like to have it at that level. And I’m also not a really a fan of imperative code, right? I’ve been doing closure programming for the past six years full time, so. I’m more of a functional programmer, right? But that’s always what I try to do. I try to avoid explicit conditionals as far as possible.

[00.15.02] Yegor: And do You have a tool? You have a software which calculates this deepness of nesting? For example, inside your CodeScene platform, do you have automated instruments for calculating that?

[00.15.16] Adam: Yes, we do. We do. So, what we did in CodeScene, was that we developed a concept that we call CodeHealth, which basically answers how healthy is your code. And the reason it’s called CodeHealth and not code quality, is cause code quality is such an, it’s a little bit of an overused term and it’s highly subjective. So, what Code Health did is we simply identified 25 factors that we know from research that they correlate with increased maintenance cost and increased risk of effects. And then we taught codescene to kind of detect those smells and using a large, large baseline library, we built an aggregate that can simply collect the information on all these 25 factors and aggregate them into a unified categorization of green code, yellow code and red code. So that’s something we can use to very quickly assess our complex hotspot, or subsystem, or part of the code. Did I manage to explain that?

[00.16.16] Yegor: Yeah, definitely. And another metric is definitely Code Complexity on which you also pay attention to. But many people criticize this metric for attributing it to code health or code quality. They say that complexity doesn’t necessarily lead to, lower quality, sometimes this complexity is better inside one method than multiple methods with visually lower complexity, but overall, the program will be less understandable. So, what’s your take on, discuss cyclomatic complexity.

[00.16.56] Adam: Yeah, cyclomatic complexity, this one’s the classics so, really really old way of measuring complexity. And it’s interesting, if you look at the research, you find that once you start to control from a number of lines of code, cyclomatic complexity in general, doesn’t add any further predictive value. However, I find it useful, because it’s useful as an indication, cyclomatic complexity is useful because it kind of tells you how many unit tests you have to write for a particular function or certain function. So that’s mostly what I’m using it for. And I find in part, in combination with a simple lines of code metric, you can get some additional insights, but on its own, it’s not a particular good metric.

[00.17.41] Yegor: And I believe that much better than lines of code are the metric which you call Code Churn. Right? Which indicates the number of changes people make to those lines of code.

[00.17.54] Adam: Yeah, that’s right. Because yeah, we started out this conversation by talking about trying to calculate static, calculate technical debt via static analysis. And the problem with that is that you get to completely flat perspective. So, you can easily figure out that this code is the most complicated. That doesn’t mean that’s the part of code that you should start investing in fixing. So, what I do instead is I calculate Code Churn, and I do that by looking in version control and I’ll simply figure out which code is being changed the most by the development team, because the code that’s being changed the most, it’s clearly the one where you should make sure that you have as healthy code as possible because you spend most of your time there. So, I always find that we kind of need both perspectives. We need to figure out where do we work? Where are our hotspots? But we also need to figure out how healthy is that code, how healthy are our hotspots. So that combination has been very very useful for me when working with large systems.

[00.18.55] Yegor: And do you think we need to, reward programmers for keeping metrics high and somehow punish them for keeping some metrics low?

[00.19.11] Adam: I think that metrics like that, I mean the desired quality metrics, they have to be on input to any software development, just like we input requirements or specified features. I really think so, and I don’t think that we can, if we put a certain quality bar on it, then that’s part of the requirements that we have to deliver on, I think that’s very important. Yes.

[00.19.43] Yegor: You know, how many times in my professional life, I’ve heard complaints from programmers who were forced or not even forced, but who were motivated by myself, through the metrics. They’re always telling me the same complaint, they were saying that we are writing code here, we’re making functionality. Our objective is not to please some of the metrics. Our objective is actually to deliver the product, the functionality to our customer and the customer doesn’t care about the quality metrics we use inside the team. So, tell, so motivating us by the metrics and expecting us to deliver higher numbers instead of delivering better functionality, is a completely wrong strategy. That’s… Many people, that’s how they complain. So, what would you answer to them?

[00.20.38] Adam: Yeah, I would say that they’re not mutually exclusive, right? It’s, I think it’s very dangerous because if you just focus on delivering new features, what you’re doing is you’re trading short term wins for the long-term sustainability of your code base, right? So, you need to make sure that if you deliver new features, you do that with the non-quality. I think that’s the most important thing, and I’m not religious about this, right? I mean, there are many, many situations where it it’s perfectly fine to take on some technical debt, the important thing is that that should be a conscious decision. You should know why you’re doing it, you should know the tradeoffs, right? As long as you do that, I think it’s perfectly fine. And I do that myself occasionally when needed. The difference is that I, you know, I know all the time with the help of every single piece of code is in the code basis I work on.

[00.21.32] Yegor: So that’s a very interesting thought, so knowing what’s going on is the most important element of managing of a software project, not forcing people or not forcing people, but knowing what’s going on and accepting the reality and understanding that our technical debt is either growing right now, or it’s stable, or maybe it’s even going down. Right? That’s what you’re saying.

[00.21.57] Adam: That’s what I’m saying. Because to me, there is much more value in trends than absolute values. So, to me, it doesn’t really, I mean, it matters of course at some level, but the most important thing for me is not the fiber code health of three fibers six, because that number is only good in a context, right? So, the trend is what actually carries the value and that’s what allows us to have a conversation. if we can move ahead safely with a feature, or if we need to take a step back and improve, what’s already there.

[00.22.58] Yegor: Another counter argument, which I often hear from programmers is that in our project, they might say, we know what’s going on, we know where the problems are, we know what the technical debt is, we know that this module has to be refactored, we know that this class, the implementation of this class was not done right. So, we don’t need any metrics, we know what’s going on. So, all these metrics, they are basically an extra layer on top of our work, and they don’t give us anything extra. What would you answer them?

[00.23.03] Adam: That’s a fantastic argument. I’ve heard that a couple of times, myself. What always happens if you dig a little bit deeper is that you figure out that on that team, they May 20 developers, and there’s always one or two people that make these claims. And maybe it’s correct, maybe they are really that experienced, maybe they’ve been there from the beginning, maybe they know exactly where their technical debt is. The problem is that the other 18 people don’t know it. The managers don’t know it. And that means you cannot have a meaningful conversation around the maintainability of a code base, unless everyone has the same information.

[00.23.40] Yegor: Good point. So basically, these people when they are saying that they’re trying to protect maybe their positions as the most knowledgeable people in the team.

[00.23.52] Adam: And that could be one motivation, definitely. And I also think that there are occasionally, there are, I think there are people that are genuinely tired of different types of tools, because I’ve been burned myself in the past by, you know, misapplications of different static analysis tools and that so, there might be that experience link as well. But if very often, I think you’re right.

[00.24.19] Yegor: You know, I usually see the reaction of managers, especially managers of higher levels. When you demonstrate them problematic places in the code, problematic places and products, you expose some risks to them, you explain what might go wrong, if we don’t do certain actions right now. They’re not very enthusiastic about this information, they don’t react positively to that. Their reaction in most cases will be, they will kick you, they’ll kick you back. They will say, okay, you are the programmer, so how come, you do it. You manage to allow the situation to happen. So, they will not react positively with the suggestions, like spend more resources on this refactoring or plan these technical debts, you know, removal in the next six months, they will start directly blaming the people who are in the project. So how would you recommend us programmers, deliver this information to managers in a way that will be perceived constructive?

[00.25.32] Adam: Yeah, so that’s an interesting angle. I think in general; my experience has been better that most managers, they genuinely want to improve. Right? But maybe I’m biased because the people who kind of call me in they’re the ones that already might have some challenges, right? And are open to kind of addressing it. I think of course, a blame game at that level, doesn’t do anyone, anything good. And I think that kind of, framing it in terms of risk rather than financial gains is very good starting point, because I tried for years to have the conversation with management about, you know, cost savings, you know, we can, I don’t know, you know, we, instead of hiring all these 20 consultants that you have planned, maybe we can get away with five, right? If we address this thing. And in a way that hasn’t been successful, and I think it’s partly because, you know, to a manager, it’s always a good thing the more people you manage, right? And it’s also where we are counterintuitive that you can get more things done with fewer people.

So, what I start to talk much more about now is risk, that, you know, I don’t point to problems, I just tell them that, you know, this area of the code, do you plan to add any features or new capabilities in that area? If you do, you have to be aware that it’s very likely that it will take you five or six times as long as you expect you have a very high uncertainty. And uncertainty is one of the things that I think help shift the conversation a bit, because uncertainty is something that no one is comfortable with. You know, as a product person, I hate uncertainty, right? It makes it impossible for me to make any promises to my customers or any commitments. And as a developer, I also don’t like uncertainty because that’s what’s causing stress and overtime and missed deadlines. So, think the quicker we can shift that conversation to uncertainty and risk, the better.

Another thing I’d like to add is that I think over the past decade I’ve analyzed 300 code bases at least, probably more. And one thing I almost always figured out was that when you find this really, really messy pieces of code these complex hotspots, it was almost never the work of a single individual, it’s almost always, you know, parts of the code where 20 further people have contributed and a half of them long gone, they don’t even work in the company. And this is another part of the problem that, you know, no one really feels responsibility over that part of the code, right? You have no, psychologists call this diffusion of responsibility. Right? So, you know, it’s not my code. So, let’s just squeeze in the sad statement and get rid of it.

[00.28.16] Yegor: In one of your blog posts, you mentioned, the broken windows symptom or broken window, I don’t know principle. Which is, can you explain that? So, I don’t do it. Please tell us what it is.

[00.28.31] Adam: Oh yeah. Yeah. It’s something, I actually learned it from The Pragmatic Programmer wonderful book. So, they had a, if I remember correctly, they have a short chapter about it. So, the broken window, it’s actually a term from sociology, where the idea is that if you have a building, the building is abandoned and someone smashes the window, the most important thing you can do is to immediately replace that window. Because if you leave it broken, then that’s a signal that no one really cares. Right? So next time someone will paint some graffiti, or they will break into the building, or they will put it on fire or whatever. And what they did with the pragmatic programmer was that they applied this to software. So, you have this piece of code, and you introduce a quick and dirty fix into it, the next developer that comes into that, detects that broken window. So now the code kind of signals that, yeah, this is okay to do, right? We can write nasty the code like this. So, you simply continue on that track and that’s kind of one reason that code deteriorates.

[00.29.35] Yegor: It’s a very good analogy. I believe.

[00.29.38] Adam: Yeah, I like it, it works.

[00.29.42] Yegor: And what are the symptoms of this broken window in a code? It’s like a code, which is written without a unit test or the code, which is improperly formatted, or the code which is functionally not working. What is the broken component here? What’s broken?

[00.30.01] Adam: And very often it’s multiple things. So, unit testing, a lack of test coverage is very, very common. You might start out with a good enough coverage, then you write a piece of code where you don’t add any unit tests, that’s clearly a broken window because now the bar is higher for the next programmer, right? We need to start by covering that mess with code and with tests, before we can do anything. But it’s also something you where we typically see in the evolution of the code. So, one thing I did in my books and that we’re having codes in is that when you find a piece of code, you can click on it, and you can kind of see the complexity trend evolving over the years. And you very, very often see broken windows as complexity trend that goes like this, it increases linearly, and then there’s an extremely steep increase and then can tend to stabilize at the much higher level. So that’s a way of bringing visibility to broken windows.

[00.30.56] Yegor: And the, probably the main responsibility of a software architect or the main technical person in the project is to fix those windows before we have many of them. Correct?

[00.31.09] Adam: I think it’s a very important part. Yes. But you know, the detecting broken windows, that’s one of the things that tooling is where we’re good at. So just make sure you have some type of automated code analysis in your development workflow, and, you know, not only are you going to detect it, but you’re also bringing visibility to it. And to me as a developer, you know, when I introduce a broken window, I like to know about it because that’s the way for me to get feedback and improve.

[00.31.41] Yegor: When I ask people about maintainability of code or legacy of the problems with these broken windows, the most common question coming from practical programmers is the following. What do I do when I’m in the project, which has tons of legacy code, and I have to work in this project, but I hate it? So, what’s the recipe for at least some happiness, some small piece of happiness we can have in such a project, because most of the work is very routine and very annoying and very frustrating because all you deal with just broken windows here and there, here and there. So, it’s really hard to find even the not broken window, all of them are broken. So, what would you suggest, what would you recommend to a programmer, practical programmer to do in a situation? When do you deal with large amount of legacy code?

[00.32.34] Adam: Yeah. So, I’ve been in that situation myself for so many years. (indistinct) And I think that it’s very important with, and maybe that’s another responsibility of the architect or the manager to make sure there is some positive reinforcement, and that positive reinforcement is also something that you can heavily have tooling. So, if you pick up this large, messy clause and you actually managed to kind of extract a small piece, you manage to cover it with good tests, then why not have the tool, give you a thumbs up and explain the improvement that you have done? I personally find stuff like that rewarding. I am. I actually am one of those people who enjoyed working on launch legacy systems and take them to a better place. So, I think positive reinforcement is key and it’s something that the process and the organization needs to support.

[00.33.29] Yegor: So basically, you look at the building, you see a hundred broken windows and you decide, okay, I’m gonna fix the window number 55, just to get some pleasure out of this work, because I’m responsible for this one particular window. And that gives you enjoyment at the end of the day. Am I right?

[00.33.48] Adam: Yeah, in essence, that’s what it’s about. And I think it’s important that like we have, we are so used as developers to have these quality gates, right? To build this is red, but I think it’s just as important to kind of push deposit, have changed us, that we do the improvements, let’s celebrate them.

[00.34.06] Yegor: And how do You feel about other programmers who are on the same team who are, who keep breaking windows and you are in this team or one of those people, or maybe just alone, just a single person who wants to fix the windows, but there is other 20 people around you who just every day they just break windows after one after another. So again, like, look at this from the psychological perspective, what would you recommend to a person like that to do if there’s the, leading the team is not an option?

[00.34.37] Adam: Oh, I mean, it’s very frustrating. I haven’t been in that situation for a long, long time, fortunately, because when I started coaching, I put up a very basic rule that every developer that I’m hiring is, has to be better than me. They have to be a better developer than I am. So, on my team. I like to think that I’m the worst programmer, which is a very good situation to be in. So, I haven’t seen that problem in six years. I remember, early on in my career, I definitely came across it. And it’s extremely frustrating, particular as a more junior developer, because you, you simply don’t have the social capital to, you know, confront people with it and have those two conversations. You can bring it up, but it’s unlikely that someone is going to listen to you. So, it’s extremely frustrating. And I I’m afraid I don’t have any good advice. I would be curious on what you would answer in that case.

[00.35.30] Yegor: Well, I recommend in dissertation for people who end up in dissertations like this is to extract a small piece out of this legacy system. Just make a module out of it, which is window number 55, and then work on this window as a separate project. So just extract the module, make it a dependency, make maybe a new repository and then set your own rules in this repository and then make it perfect, make it beautiful, and then make the large legacy code. Just depend on this dependency, depend on this artifact and that’s it. So be your own manager, be your own architect, be your own manager, try to become your own manager. And in most cases, I believe other people and your managers and other the team, they will not be against that because who cares? I mean you still use the functionality; we still have this piece of features from your, from your window, which was broken. Now it’s fixed. So, most of the people will continue breaking windows and you will not be affected emotionally by that because you don’t see those windows. All you see is just your own window, which is perfect, which is fixed. What do you think about this recommendation?

[00.36.35] Adam: I like it. I like it. It’s little bit familiar. I had a chapter in my book that I called where I wrote about the splinter pattern, which was basically I was addressing a different problem, but it was basically how do you refactor a massive clause, that’s also being heavily developed in parallel by many, many other people, right? And I I’ve come to the same conclusion there. That that’s one strategy that works to kind of, you know, you need to extract those two small pieces. You need to treat them as separate components that you can fix in isolation without caring about the rest of the as, but I never talked about it from your perspective. So, I kind of like it, it resonates with me.

[00.37.13] Yegor: And you know what I see also, or sometimes very often actually, when the team is, is in a mess right now in most of the windows are broken, then people tend to find many, many reasons against the quality metrics. When you try to introduce some tools or mechanisms, or rules or principles about quality. And you say that from now on, we will pay attention to the amount of technical debt we have because it’s important. So, if the technical debt grows, then we basically take a pause for a few, maybe weeks or days or months, and we fix it and return the technical debt, the amount of technical debt back to the normal numbers. Then most of the people who are on the team right now, they will give you tons of arguments against this approach against metrics in general, against checking the technical data amount in general, against putting the project on pause and not delivering the functionality. The tons of reasons will be there. So, and it will be hard to argue against those reasons because these people will be in majority very often. And that’s why I think in the industry in general, it’s so easy to find people who, when they hear the word metric, when they hear the word measuring of quality objectively, quantitatively, they will immediately jump into the analogy of, maybe tomorrow you’re gonna calculate the number of lines of code we write. And that’s it. After this analogy, all the discussions are stopped. Everybody will laugh at the end of story. Have you seen that happening?

[00.38.50] Adam: Yes. Yes. I have seen that occasionally. And I’d like to think there are two reasons for it that the first reason is of course, that metrics have been horribly misused in the software industry and they still are. And the second reason that I think is even more important is that most businesses simply don’t value code quality. It’s not a first-class citizen. If it would have been, no one would be questioning it. No one would metrics because, you know, as a startup founder, I’m a technical founder, right? But I had to learn all this financial terminology. I have to understand what the is, (indistinct) MRR, (indistinct) and you know, all that net retention, all that stuff. I had to learn that. And everyone understands that. I mean, the health of the whole company depends on numbers, right? I’m not questioning it. Do we really need to measure how much revenue we’re bringing? Do I need to make projections of that? No, it’s no one would question that. But when it comes to software, since it’s so abstract and kind of, you know, it doesn’t have this, the same visibility, we don’t have any KPI’s in a way we have financial KPI’s for software, then it’s so, so easy to make it something like, yeah, yeah. It’s something for the development team. And if you push it down as a manager on the development team, what happens is that it just becomes extra work, right? It’s something that someone will hold against you. It’s something you have to do where you could have spent your time hanging around the coffee machine or writing some extra code or whatever.

[00.40.18] Yegor: Right. And some people actually feel comfortable of this writing code. Let’s, remove the hanging around the coffee machine because that’s definitely one story. But the second story is people are, the second story is about people who really love to write code the way they write code. So, they don’t like changing the style or the way they write code. They feel comfortable staying where they are. And when you, as a manager or a technical architect, or as another programmer, just a fellow programmer, come to them and say, now, from now on, we’re gonna pay attention to quality. For them it means that they need to relearn something. They need to improve themselves; they need to basically abandon some of the styles of work they they’ve been having for years. And that means stress for them. And that stress immediately triggers the, the negativity and reaction against the people who are trying to introduce that to them. So, you look like a teacher for them, you look like a crazy professor who, you know, doesn’t like, to give them the good mark for the exam. And of course, they get angry. So, the question is how psychologically, emotionally we can get on board with these people. And actually, instead of fighting with them, somehow get them, get their buy in from them. So, they will say, okay, I agree to, to learn something new. I agree that my code is not good right now. And the next year I need to improve it. So that to satisfy your, your metrics, which you introduce. So, let’s the question, how to become friends with them, how to get them on board.

[00.41.53] Adam: Yeah. And it’s a, it’s really important issue because forcing a set of metrics on someone is usually not a good way to go because any metric can be gamed, of course. And the moment you start to game a metric, you lose important information. You make the whole situation worse and, you know, the metrics just become ridiculous. So, I think it’s really, really important to get a frame of reference. And what I mean by that is that particularly in larger companies, I mean, I was in that position myself only in my career. I started work in software 25 years ago. And the first years I spent, relatively small department within a larger company. And I like to think that after a couple of years, I thought of myself as a pretty good programmer, then what happened to me was that I went to my first software development conference, the ACC conference in England. And I remember going to that conference thinking, hey, this about C++ I’m a C++ whistle. I know everything there is to know about it. And the very first session was Hanley talking about multi-Friday, C++. And I, it took me like 10 minutes to realize that, hey, there are very different levels to this game. I’m definitely not a good programmer. I’m a mediocre programmer at best. So, to me, this has had a very, very motivating effect. I kind of, I realized I will never be that good. Right? But I can definitely improve. There is a lot of ground to cover here. So, to me, that kind of triggered on, you know, a desire to learn more, to evolve, and also think that we don’t have to, I think that’s important to get that external frame of reference. So, I think that taking the team, going to a conference, invite external speakers, I think that’s very, very important because it can start to bring up the discussion and give you that frame of reference. What also think is that when introducing things like quality gates and metrics also think it’s important to give people the time to learn. So instead of doing this big bang thing, I’m a fan of kind of introducing things it relatively gradually and make sure that I always explain why we’re doing this, why this thing is important.

[00.44.07] Yegor: That makes sense. And let’s turn a little bit our conversation to the technical territory. Do you think code quality is a language specific thing? Do you think certain languages programming languages are more of a high quality? So, the code which you write in those languages, they just naturally will become of high quality and some languages are more prone to errors and troubles with the quality?

[00.44.38] Adam: In general, no. I don’t think so because I’m analyzing code in all kinds of languages. And I don’t really see a correlation in terms of language features or language capabilities. What I do see is that the community around different languages have a huge impact on software quality. So, you know, when I prepare a talk and I’m looking for a, a good examples and different code smells, I always know that, you know, if I want to find really, really in massive unit tests that overuse mock frameworks, then I look at the.net code basis If I want to find some real spaghetti code. And I always kind of Google GitHub trending С++. And if I want to look for over abstracted code, then I always say, go for Java code. So, I like to think that there are community practices to kind of influences the quality that gets implemented. I don’t think it’s the languages themselves necessarily.

[00.45.38] Yegor: And who do you think we need to blame? I mean, let’s use this word blame for the low quality, programmers or programming languages? Like your previous answer, actually give the, give me the impression that you would answer programmers, right? The communities of programmers. Okay. Let’s move then rephrase the question. Who would we blame individual programmers or common practices in the community around languages?

[00.46.06] Adam: Oh, this is actually quite hard because it’s not easy to break community practice as an individual. You’re going to get question. And it might also, I mean, in some cases it’s actually better to follow a slightly worse principle, as long as it’s not directly harmful, because it at least gives you consistency in your code and consistency in your solution together with your team. But yeah, I do think that community practices, they need to be questioned, right? I’m not the good, I’m not a big fan of things like best practices, because they’re usually, you know, they’re very often they become a way of just ending our conversation instead of starting it.

[00.46.49] Yegor: You know, I very often hear arguments. Like, I mean, this Java, come on. What do you want from me? I mean, that’s not possible to make it high quality or it’s C++ it’s a complex language. So that’s why our code is so difficult to understand. And there is the technical debt is so huge. So that’s because we use this framework. That’s why the quality is low. People say it very often. So, what would you answer to them?

[00.47.11] Adam: Yeah, it, it’s why we were common and what I did was that when I worked as a consultant, what I, we often did was that I refactor that code to have that conversation. And I, you know, instead of talking about how we could do it, I kind of showed that, yeah, this is the way it could actually look. And it was code. I did that, you know, completely separate, separate branch, something that wasn’t merchant production, but it kind of gave me opportunities to show before and after. And I think that so many developers myself include, we learn pretty well by examples. So, if we can see that, hey, this is objectively simpler than this. Then that’s a pretty strong argument. You show that it’s possible. And you show that there are actually some pretty simple patterns that you can follow. And I like to think that it applies to virtually any language with the possible exception of assembly.

[00.48.09] Yegor: And you think it’s a job of team or managers or architects to train people, to teach people, to help them learn how to write better code, or we, as let’s say, architects and managers have to just enforce certain metrics and rules and say either you write the code, we expect you to write or go back home do your homework, learn something. I mean, improve your style and then come back. So, what’s your take on that? We teach people, we train them, we mentor them, or we just set the quality bar high and expect them to satisfy our requirements?

[00.48.45] Adam: No, I think we have a huge responsibility as managers and architect to encourage a culture where everyone is constantly learning. And I think a lot of the time, it’s not so much about educating or doing the education yourself. It’s more about removing all those barriers that normally exist in all organizations. So, I used to have this trick back in the day where I was still, I am working for someone else. What I used to do was when I went to job interview, was that I always had this question. You know, if I want to buy a book or programming book, what’s the process? And any company that had a process for that, I turned them down because I think that’s one of those signals, right? If some developer wants to spend time learning something, and I learned by reading, right? That they, and just by the book, it doesn’t cost anything, right? The time a book costs it. I mean, it’s the time it takes to read a book. That’s the cost, not the price of the book. So just encourage things like that, make it simple for people to learn, use the intrinsic motivation of each individual. I think that’s very important to build on and that’s will also benefit the whole business.

[00.49.57] Yegor: You know, many businesspeople will tell you that. Now, if we train people, if we mentor them, we help them to become better and invest a lot of time into that eventually what we get in the end is that they quit and go work for larger companies with larger paychecks. So, in the end business loss losses with these investments loses these investments.

[00.50.21] Adam: Yeah. It, it’s interesting. It’s very shortsighted in a way, because if you look at numbers from the industry, you see that most people and they don’t stay particularly long at the job anyway. Right? And I also think that if you encourage that learning environment, if you make it very, very simple and fun to learn, because it is fun, most people enjoy it. Then your kind of also preventing or not preventing necessarily. But if people enjoy working for you, they’re going to continue work for you. Right? So, I think that’s an important component and, you know, having cool stuff that they can work on also helps in retaining developers.

[00.51.04] Yegor: Well, enjoying, like you said, the enjoying part for people is not actually improving your skills every day. It’s for some people, this is the enjoyment, but for majority of people, I believe for maybe, you know, 80% of large majority of people, enjoyment is actually being on top of the learning pyramid, not being at the bottom and always look up to mentors and smarter people, but always look down and tell people that I am the smartest one. So only the minority of people would like me really to enjoy growing while most of the people, the majority enjoy relaxing and teaching others, maybe that’s my understanding of, or like psychological, a breakdown of people profile. So, it seems to me that if you, put people into a stressful position where they constantly need to improve and learn and to become better, then this is not exactly the enjoyment for them. It’s like a training territory for them, which they will have fully pass in order to get to a more comfortable territory in another company where they will become mentors and they will become architects and so on and so forth. So don’t you think that by cult, by encouraging and encouraging your team and cultivating the culture of constant training and constant learning, you only will stay with the best people, but the majority of people which will use your territory as a training base and will, after that, will jump to other companies.

[00.52.43] Adam: I’m not sure, maybe you’re right. I haven’t thought that deeply about that. What I’d like to think is that it’s also, I mean, one way of kind of limiting that stress as well is to make sure that you have very, very clear goals and that those goals are something that you have in common with your peers. Because you know, learning from me and education for me is not necessarily only going to take a course or reading a book. It’s also something that can happen all the time on the job. You know, if I have on, if I know that I have the freedom to try out something new, right? Maybe I can try a new solution, right? Something, I came up with myself, then that’s also important learning. If I have the opportunity to pair together with my one, my peers at any time, then that’s also a learning opportunity. So that’s kind of what I mean with the culture of learning that you kind of remove all those barriers, right? And if you need those barriers, then I think it’s a clear sign that you have an as a manager, you haven’t managed to hire the right people.

[00.53.50] Yegor: So, your criteria when you hire people, is that they have to be better programmers than yourself. Am I right?

[00.53.58] Adam: Yes. They have to be better at developers than me at some aspect of what we do. Definitely that’s important. I never compromise on that.

[00.54.06] Yegor: And do you check their quality, their code when they come to your, to interview with you? Do you ask them to show you the code they wrote before? Do you check the code? The quality of it visually?

[00.54.19] Adam: Yes, we do. We do. We actually, I’m not a big fan of these typical whiteboard interviews. We never do them. So, what we do instead that to we ask people that, you know, we take a look at their GitHub account and the people that kind of move on the in-person interview, one of the steps is always that we run their code through codes in, and then we have a conversation around the findings.

[00.54.44] Yegor: That’s a good idea.

[00.54.45] Adam: And it’s really, really interesting, and where I’m personally, again, I’m never after perfection, right? I think it’s perfectly fine. You might have some code it’s not ideal. The interesting thing is the conversation you have around that. Why is it that way? What could be done instead, that’s much, much more interesting. So that’s what we do.

[00.55.06] Yegor: That’s excellent idea. I will try to do the same. So, you’re basically around some static analyzers, some quality checker, it will show some complaints and then you ask them, what do you think about that? Why did you make the code better and so on and so forth, right?

[00.55.21] Adam: Yeah, exactly. And what you will find is that so many of those developers, they have already kind of thought about those things. So, they are kind of, you know, they have an ID and they kind of, what you kind of want to show that is that you, as a developer, you have the ability to kind of step back. You are not your code. Right? And you can have a conversation around it. I find that valuable as well.

[00.55.45] Yegor: Okay, my last question to you, you wrote the book a few years ago called Your Code as A Crime Scene. So, what’s in the book and why our listeners should buy it and read it. Just give us a brief, quick explanation. What’s there?

[00.56.01] Adam: Yeah. So dear listener, you should actually buy the follow up software to sign x-rays. I like to think it’s the better book, because I learned so much between writing those books. Both books are about how to build a maintainable code and a lot of strategies for succeeding with that. And those strategies, they take a lot of inspiration from psychology that we apply on top of our technical engineering foundation. And there are a bunch of techniques that will help you to prioritize technical debt. There are techniques for addressing technical debt, but there are also a bunch of techniques for kind of measuring and visualizing the whole team dimension of software in the context of architecture, which is something that’s, I would say, just as important as any properties of the code. So please check out software to sun x-rays.

[00.56.52] Yegor: All Right. Thank You very much. We will definitely do so. And thanks for coming for this conversation. I enjoyed it. I mean, I took a number of interesting thoughts, and I will try to practice them in my life, my work.

[00.57.08] Adam: Yeah. Thanks a lot for inviting. I really enjoy this. My pleasure.

[00.57.12] Yegor: Bye.

[00.57.13] Adam: Bye.

sixnines availability badge   GitHub stars