An open letter to my former company before moving onto my next job.
Yesterday was my last day at GFG eCommerce Technology as Director of Engineering. After 4 wonderful years, I felt I couldn’t leave without first handing down some lessons I learnt during my journey. What follows is an extract of the internal email I sent to everyone.
It was meant for internal circulation only, but I thought that those same lessons could be useful for a broader audience.
I edited it to leave out information and names that can’t be disclosed for various reasons.
tl;dr; Short goodbye for lazy readers
So that’s it, my friends. Today is my last day at Rocket Internet -> Rocket Labs -> GeT/GFG.
What a journey! The best years of my professional life so far. And I owe it all to the most incredible team I ever worked with.
Trust me when I say that the culture and the skillset we have here is second to no one. We truly rock.
Now, I have a few things to say and leave as a legacy to you. If you want to spend a few minutes then just keep reading, otherwise I’d like to thank you for all the time we spent together and the opportunity you gave me to grow together.
Keep up the good work!
A list of things worth to be remembered
When I joined [Project name], we had two teams only: maintenance and feature. You can guess what the two teams were doing. We were also supporting our customers by committing code to their adapters in their SVN repositories. We had no devbox, everything had to be setup by hand and on average it took 2 days to be ready to develop something.
My first PR was a one line CSS fix. Best Dev Ever!
Back in the days we used to discuss in PRs things like “brackets on a new line”, or “please add a space”. I hope today everyone delegates this to code standards.
[Project name] was started without the usage of namespaces, even if they were already available in PHP.
I saw a Club Mate for the first time at the office. I tried it once and never drunk it again. The perfect companion for the Hawaii Pizza.
I brought the Read Model concept into [Project name] because we were hitting performance limits. It worked quite well for the Quality Control list, so I planned to apply it to the Catalog Product view as well. At that time we were not using feature switches. I worked for like two weeks on that functionality and we merged a PR with an untold amount of changed locs. Needless to say that everything went south. 3 months after joining, and few days before Black Friday, I screwed up with [Project name] so badly that nothing was working anymore, MySQL couldn’t keep up with the load and we found ourselves at the office at 5am in order to fix everything. We reverted few commits (not easy at that time) and we lost like 1–2 weeks of work. Boy if I learnt something that day! One of the hardest yet precious lessons in my career.
I remember the countless parties in Rocket or the ones we used to throw ourselves. Our team was famous for being like biblical locusts. They arrived in mass, outnumbered other teams, make the most noise and consume all available resources (i.e. beers and food and space). But, hey, we really were the party soul.
We hit a headcount of 80 in a crowded ground floor office. At some point we used to communicate to each other by shouting across rooms, for the joy of the rest of us. Some of you remember the suave voice of one of our employee and that you could hear him talk from a tens of meters distance.
The number of tennis table hours we played, especially in the former offices, is roughly equal to those spent developing [another project name].
When management started the Friday beer (hasn’t always been a thing) we all knew immediately this would’ve brought the office entertainment to a whole new level (and it did).
The first version of [another project name] came out only 3 months after the kickoff, with a team of three developers using a language they never had used before (Go).
If I could talk to my past software developer self from 5–6 years ago, I think he could barely recognize himself in me. I started from the belief that software development was the art of coding elegant software and I ended up today with a totally different mindset, learning countless lessons in the journey.
The most precious lesson I learnt about software development is that our discipline should not be called like that at all. The reality is that we are developing sociotechnical systems. We are designing the interactions between systems developed and maintained and used by humans. Ignoring this fact and its implications on our day by day jobs leads to poor choices and outcomes. We are not developing software in isolation, we always strive to coordinate the efforts of many people and teams. And by doing that, we try to align the communication structures of our company with the design of our software systems (see Conway’s Law). Any developer willing to master the complexity of her job needs to understand and absorb this belief deeply.
About our systems infrastructure, I see we’re definitely going in very specific directions, especially when we look at our recent past. We went from physical servers to virtual machines, and I heard people complaining “yeah but physical machines are the real thing”. Then containers came, and I heard people saying “yeah but containers are troublesome, you can’t be serious with those”. Then serverless came, and again I heard people saying “yeah but if you don’t manage your infra this is going to be a big problem and I don’t like it”.
Can you see a pattern here? My opinion is that our infrastructure environments are becoming a commodity, and that we’ll take them for granted as we do now with the virtualization of resources. Just wait for it.
On the software design side, I learnt three important lessons and I’d like to pass them to you.
We shouldn’t identify programming languages as OOP or FP ones only
And we shouldn’t identify ourselves as OOP or FP programmers. The reality is that, in order to achieve a higher level design in terms of robustness, completeness, expressiveness and elegance, we need to leverage techniques from both paradigms. Every modern language (PHP and Go included) at this point in time supports classes and functions as a value, which is all you need to leverage both paradigms. I wrote an ironic post about this one, but I’m sure it conveys the full idea of what I’m summarizing here.
Develop a healthy obsession for software design
Remember: code is a by-product of your understanding of the domain you’re modeling. Even if you think you’re just coding something, the design is still happening in your mind at unconscious level. But while designing is as cheap as having multiple alternative models drawn on a whiteboard, production code is a liability that you won’t easily change in the future. Before diving into coding, take hours if not days thinking about at least 3 possible alternative solutions for your problem. If you can’t, you probably haven’t understood your problem enough.
Domain Driven Design is so far the best design approach to model complex domains. And I’m not talking about tactical patterns that are simply part of our everyday dev toolbox. I’m talking about Event Storming, Context Mapping, competing heuristics, business language, temporal modeling. I’m talking about telling the story of a system rather than making a static snapshot of relations among its parts.
Challenge your basics
The software development community learnt so much in the last years that we should constantly challenge the knowledge we acquired when we started and that we still take for granted after all these years. If you ask me now, for example, I’ll tell you we shouldn’t use inheritance anymore. It makes our code way more rigid and difficult to manage. We should only use it in that 1% of cases when two classes have semantic correlation, zero or minimal behavior, and an almost identical set of properties. Otherwise use composition. Simple as that.
Another example is the holy DRY principle, which is completely misunderstood by the majority and makes your code looks weird in the extreme attempt of the developer of not duplicating a single line of code. We should start doing the opposite: duplicate by default.
You may or may not agree with me, but that’s not the point. The point is that you must be ready to challenge your most inner beliefs at anytime. It’s painful and makes us feel insecure, but it’s the only way to grow as professionals.
What does it mean to be a Senior Software Engineer?
I heard this question a lot in our company so let me give my 2 cents here. Be a Senior Software Engineer is not about knowing a lot of programming languages. It’s not about knowing one of them inside out. It’s not about being full stack or being able to bring up a service from scratch. No.
Being a Senior is about Leadership. Being a Senior means you are not afraid of making decisions and you take responsibility for them. Being a Senior means you care about your team members, their growth as individuals and their cooperation for a higher purpose. Being a Senior means you are constantly learning because you want to become a better version of yourself. Being a Senior means you have a holistic view about your environment, the problem you’re trying to solve, the systems in place and the rules governing them. Being a Senior means you’ve understood that your ultimate goal is not to produce software. Your ultimate goal is to improve the life of other people by leveraging your knowledge.
I’ve formally been a manager for some time now, and I’ve also met and talked to a lot more, each with with different styles, beliefs and methods. This allowed me to form my own set of principles when it comes to manage people, and it worked pretty well so far. I’d like to share with you three of them, for I think they’re the most relevant and the ones I used most while in our company.
Let leadership emerge
A manager can be appointed. A leader can’t. A leader is recognized as such by her peers. Sometimes leadership is not even focused in one person only, but is shared across a whole team. As managers, we should always let leadership emerge by itself and act accordingly. Responsibilities should be given to people who already implicitly accepted them. Violating this principle results in demotivation, lack of trust and discontent.
Adapt your management style to the environment
According to the Cynefin framework, there are four kind of problems/environments: trivial, complicated, complex and chaotic. A team or a company always falls in one of those categories. It’s important for a manager to understand which type of problem she’s facing. Her management style must change accordingly, or her efforts will be not so effective if not counterproductive. When a problem is trivial, we go by the book. We follow rules and best practices and we only need to make sure that everyone does. When a problem is complicated, we categorize it and we act. We leverage the knowledge of experts and we trust them to find a solution. When a problem or an environment is complex (that’d be us as a whole company and most of the companies out there), we don’t see clear cause-effect correlations, and that’s why sometimes you can’t just solve problems, but you can only manage them. What we should do here is let the situation evolve, sensing it and responding accordingly. This happens in a never-ending loop in a normal company, and this is where managers find their raison d’être. If there were no complex problems, people could simply follow a list of good/best practices to make a company thrive. Finally, just for your curiosity, a chaotic environment is the one where a manager needs to act immediately and command in the attempt of bringing the situation back to being complex or trivial. She’ll think about the consequences later. I’m pretty sure that as long as you stay in our company, you won’t see this kind of environment.
Choose the right delegation level, then trust people
Usually people think that a manager simply decides whether to delegate something to someone or not. Unfortunately things are never so binary, and as a matter of fact I have 7 delegation levels in my scale, where 1 means “I decide and I don’t need anyone to know or approve my decision” and 7 means “You decide, I don’t need to know or approve your decision”. It’s a precise duty of a manager to locate every responsibility, every decision in the right delegation level. This is crucial for aligning expectations and for being sure that everyone knows what has being required from her. Better be super explicit on your delegation levels rather then think that your decision is so obvious that doesn’t need to be explained or verbalized. It may be obvious for you but not for the delegate. Be thoughtful on that.
Thank you, everyone.
Berlin is small. See you around.