This article was originally published on Thorsten Ball’s personal blog, and was translated and shared by InfoQ Chinese site with the authorization of the original author.
As of April 2022, I will be 10 years old as a professional programmer.
I got into programming earlier than that, just didn’t get paid. As a teenager, I created websites and IRC bots and wrote short Python scripts. Then I stopped and played guitar for a few years. In my twenties, and by rather coincidence, I discovered again how much I love programming. At the time, I created another website as requested, and found that the Web has changed a lot (now HTML5) in the time I’ve been away.
So I wondered if programming was a better career choice than continuing to study philosophy in college. Robin answered this question for me, and he graciously offered me a paid internship.
It’s been 10 years now, and to be honest, it’s not a significant marker for my upbringing as a programmer, or for my career. But realizing that 10 years have passed, I thought it was necessary to stop and think.
Here are some disorganized thoughts that come to my mind as I look back over the past 10 years. The things I learned, the things I didn’t learn, the things I changed my mind about, and the things I never thought I would believe I believe now.
To a large extent, they stem from the context in which I was involved in software development: as an intern at Robin, as a software developer at a small German startup , as a senior software developer at a startup within a large German company , and now As a senior engineer at a fully remote, asynchronous US startup . Take this next sentence as a disclaimer, and I bet this post would be very different if I were working at a game studio, hardware company, and big tech company.
Daredevil is undervalued
Most of the programmers I follow as role models share a trait that is rarely mentioned: fearlessness.
They’ll drill into an unknown codebase without fear. They’ll be unafraid to open code that they suspect has an abnormal dependency. They will start working without knowing how to get it done.
Seeing others be fearless is very inspiring, but becoming fearless myself is one of the best learning accelerators I’ve found.
You can’t predict the future; try it and you might get yourself in trouble
We all know that the future is unpredictable. But it took me years to really think about this when programming.
For the first third of my career, I would think: We’re going to need this, so let’s build it now. In the second third, I’ll think: We might need this, so let’s get ready. Now, I’ll think: We don’t know if we’re going to need this, it’s a possibility. Sure, it looks like we might need to, yes. But things are changing all the time, so let’s build what is now known to be needed.
Write code that is easy to test
Write code with this philosophy in mind: I don’t write code just for the computer to execute, I write code so that it’s easy to read and understand, or easy to delete, or easy to modify, or easy to review.
Nothing really matters except bringing value to the customer
Type safety, 100% test coverage, the ability to express business logic fluently in code, perfect development tools, efficient systems that don’t waste resources, use the best programming language at work, elegant API design, fast feedback loops, Well-written code – these are not the goal.
The goal should be: provide value to your customers, solve their problems by delivering software, and keep repeating the process. The previous things can help you do that—faster, cheaper, more efficient, safer, happier—but they are not the goal. The goal is to provide value to your customers.
Pitfall: Writing software is often easier than delivering it. But delivery is what counts.
perfection is impossible
I might have thought that was possible, but now I’m sure it’s impossible. Everything is a result of trade-offs.
You can never be 100% in everything you care about. Something has to give in. When you think you’re perfect, you quickly realize that you’ve forgotten something.
My aesthetic has also changed. Instead of looking for perfect beauty, I now think that beauty is the procedure that succeeds despite its flaws. Take a look at that applet, although there are 17 TODOs in it, it still maintains the development of the Internet.
It doesn’t matter if you can’t connect it to the business
You can refactor a codebase, clean it up drastically, make it easier for everyone to understand, and make the codebase easier to scale, but if the codebase is removed after four months because the project doesn’t help the business , then none of this matters.
You can spend weeks adding tracing and observability to all the code you write, but you’ll realize that no one is going to look at it because the code runs three times a day and never causes any problems.
You can tune and optimize your code to run so efficiently that a company can halve the number of machines needed to run the code, although the cost savings is trivial compared to the salary you get while optimizing.
You can spend your time doing great technical work, but it’s still a waste of time.
Figure out what the rule is trying to prevent, then consider the optionality of that rule
If you had asked me 5 years ago if TDD, clean code, software craftsmanship, and other schools of thought were dogmatism, I would have said, “No! Can’t you see that? Clean, good code matters!”
Now, looking back, I shake my head when I think about whether the rule “a method should not exceed 5 lines” is useful.
It’s not about the rules! It is the problem that these rules are designed to prevent. If you don’t have the problem the rule is trying to prevent, or you can prevent it in another way, then you don’t need this rule.
Writing tests gives you confidence that the system works
Don’t worry too much about whether a test is an integration test or an end-to-end test, a unit test or a functional test. Don’t argue with others whether private methods should be tested. Stop worrying about whether you should access the database in your tests.
Instead, write tests that let you know if the system is working properly. Ideally, it only takes 3 clicks and is done within 1 second.
It took me a long time, a lot of useless discussions, and a lot of code bugs to learn about this.
Best practices are usually based on the assumption that you know what the code is supposed to do
If you know exactly what to build, then best practices and patterns can help you with advice on how to build.
However, if you don’t yet know what the program is supposed to do, or what it’s going to look like in four weeks, there are some best practices that make things more difficult.
Some practices are great for rewriting, but terrible for exploring.
Using someone else’s code is not as good as I thought
I started my career writing Ruby and JavaScript code, and since there are package managers available, I always ask, “Isn’t there a package that can do this?”.
Common sense tells us: if you can, use a library instead of writing it yourself. Reuse code as much as possible. Don’t reinvent the wheel. Don’t copy and paste. This has been my belief for many years.
But this also has drawbacks. Sometimes it may be better to write a function yourself than to add a dependency.
Dependency has a cost. You must keep them up to date. They can increase compile or load time. They add weird stuff to stack traces. And, a lot of times, they do a lot more than you need, which means you’re giving a lot more than you’re getting.
When you glue other people’s code together, there is a very real danger that the complexity of the glued code will keep building up. But this is where you least want complexity. It hides complexity. All you have to do is expose as much complexity as possible and find a way to remove it.
Sometimes it’s better to write your own than to use someone else’s code.
Some companies do it, some companies don’t, but no one is perfect
There is a big difference between developing software for a software company and developing software for a company that has to hire software developers as a last resort. It’s a joy to work at a company where leadership understands software and how it’s produced.
Having said that, I don’t think one company can solve all problems. Every company has room to play to some degree.
Investing in feedback loops is never in vain
I’ve never regretted improving the feedback loop. Faster testing, better test output, faster deployment, turning a manual feedback loop into something with one-click feedback.
Be warned though: once you see that software development can have really fast, efficient feedback loops, you’ll crave it forever.
Always leave something unfinished at the end of the day
A failed test, a compile error, an unfinished statement, end your day with one of those, and the next morning you can sit back and continue your work, skipping the “Well, I should have today” doing what……”.
Nothing gets me started faster than failing a test I need to pass.
Perfectionism is a trap
Perfectionism is based on lies. You can never be perfect. There will always be something out of place. Accept imperfection, deliver and keep building.
Aim for 80% and treat the other 20% as optional. Leave yourself room to breathe freely. You might end up at 99%, who knows?
If you want to do good work, you must first sharpen your tools
I put a lot of effort into tools: Vim, git, shells, Unix environments, testing frameworks. I really enjoyed spending a Sunday morning in Vim configuration.
But it’s also possible to overdo it and get stuck in the configuration phase, unable to extricate yourself, doing endless tinkering. You have to use the tool before you know how to configure and use it best.
Hiring is hard
I’ve done hundreds of interviews now and the most important insight I’ve gotten is that hiring is really, really hard. Interview evaluations are influenced by a lot of random factors, and people can oscillate between “strongly agree” and “strongly disagree.”
I often wish there was a way to find out if people had a “gone” gene.
Most Important Developer Trait: Roll Up Your Sleeves Because It Has to Be Done
All the people I like have one thing in common: they do their jobs without complaint. They know that some tasks are not fun, exciting, and even less interesting. But because someone has to do it, they do it.
Work on the same codebase with others over an extended period of time
Working with a group of people on the same codebase for years, nothing has helped me improve my software engineering better than this.
You will see how decisions are made.
You’ll see ultimately what matters and what doesn’t.
You will see the true scalability of your code when your colleagues try to modify it 3 years after you wrote it.
You’ll see if your prediction – we have 2 now, but I’m sure there will be 5 in the future – will come true and take that outcome into account when making other predictions.
There will be some codes that you will regret, and there will be other codes that will make you happy. Reflect on the difference between the two and you can learn to improve.
You’ll see tools fail just because something changed somewhere, and while it’s not your business, you still have to fix it.
For some parts of the software you say “I never thought about this in three years” and treat them as treasures.
You’ll see which parts of the codebase are difficult for new colleagues to understand and which parts they will gain right away.
You’ll see what the code you wrote looks like 4 years from now.
Learn about the full stack
For me, few things inspire me as much as hearing the phrase “you don’t necessarily need to know how it works.”
Of course, I probably don’t need to, but I can’t if I don’t manage to understand how GC works, or how Unix works, or how multithreading works, or how databases store data, or how interpreters and compilers work to this extent today.
It’s also good for my work. I can make better technical decisions because I’m able to weigh the trade-offs more accurately and know what’s going on under the hood.
Typing can be a bottleneck
I said it before . Don’t let typing be the bottleneck.
Code reviews are not airtight
For a long time, if I missed a bug during a code review, I thought it was my fault. I missed it! How could I have missed it? Such an obvious bug!
Later I found out, it’s not just me: other people miss bugs in code reviews. In fact, they have accepted the situation and have no qualms in saying that code reviews are not airtight. I breathed a sigh of relief.
This changed my mind about code review: it’s an imperfect thing that needs to be combined with other ways to validate code.
Not every code review is worth it
Not every piece of code needs to be thoroughly reviewed. Sometimes, if the risk is acceptable, a quick “LGTM!” will do. This unlocks the potential of colleagues, maintains momentum, and builds trust implicitly.
negativity breeds negativity
If you succumb to negativity, then you become more and more negative. You always get a lot more than you want.
It’s viral. It starts with sarcasm, then turns into cynicism, and eventually “everything sucks.” Before long, no matter what you do, ask “Why do you do this?” Over time, people will hide their excitement, joy, and thoughts from you.
It’s too easy to be a negative person. I think, in a way, pointing to something and saying it’s bad, then shrugging and saying, I’ve long expected that it’s not a good thing (everything is a bad thing, right?) It’s easy to do, too It’s easy to be mistaken for an engineering mindset that can spot bugs and worst-case scenarios (it’s not).
The hard part is seeing things as they are, seeing the good in them. Encourage other people’s ideas, even if they have little to talk about. Create and nurture happiness. It’s challenging.
So, eventually at some point, I decided to get over the negativity and try to do something challenging. So far this has helped me a lot.
You can’t do everything 100%
I can’t do everything equally well all the time. I can’t write a book and make progress in my career, be a great dad, set records in the gym, and read two books at the same time. This state of affairs will not last for a week or two. This is not sustainable.
Now, I switch between the important things: when I want to make progress on a particular thing, I focus on that thing for a while and accept that other things have to go into hold mode.
Code has weight
Code has weight. Every line of code you don’t need is ballast, it adds weight to your codebase, which makes it harder to control and change direction. The less code you need, the better.
The code must be easy to read, it must be tested, it must remain compatible, it must remain secure, and it must work. Even if it’s not doing any useful work right now, it’s fine to have it around, no? no. Be sure to delete it and move on. If necessary, just restore from version control.
The same is true for testing, if only I had known.
programming is part of my life
Since I started as an intern, I’ve spent a fair amount of time outside of work programming: reading technical books, writing books, doing side projects, blogging, giving lectures, going to conferences, learning new languages and tools.
There are companies out there that don’t care about your college degree as long as you can show that you’re really good at programming, which has been my motivation for years.
I like to spend time programming outside of work, but not all the time. Some feel like work. Some technical books are exhausting to read. But there are just some things that don’t feel good when you’re doing them.
My career would be completely different if I only programmed and learned to program in my day job.
computer is fast
Building web applications makes me think 100ms is fast, 50ms is really fast. Writing a compiler taught me that 1 millisecond is an eternity for modern computers.
I still love programming
Some of what I’ve written might be said that I’ve grown cynical over the years. Did I mean “nothing matters, perfection is impossible”?
No, quite the opposite. I care about things, and I care a lot, but I care less than before, but I still like programming so much.
Follow me on Twitter ( @thorstenball ), email me ( [email protected] ), or read my books on interpreterbook.com and compilerbook.com .
View the original English text: Professional Programming: The First 10 Years
The text and pictures in this article are from InfoQ
This article is reprinted from https://www.techug.com/post/ten-years-of-programming-experiencebe3e42d25847a64eecdc/
This site is for inclusion only, and the copyright belongs to the original author.