Pass the New Manager Review
Leverage its wisdom to clean up your code and make a great first impression
Walking in as an organization’s new tech manager or senior consultant is always a challenge. I like to work in places where I can make a positive impact. That means finding the organizations with legacy systems and pockets of “but we’ve always done that” stubbornly enforced in the code. This is where the change and challenges are, and I thrive on that.
I’ve had many titles but the job’s always the same — walk through the door, scope out the teams and figure out where we can make things better. As a tech manager, how do I get to know your work?
It’s simple. I read your code. Before I walk into the conference room to introduce myself for the very first time I’ve already read your code — and the log files. I’ve taken a random sampling of what you deployed at least six months ago versus your latest programs. I like to check for growth. I’ve taken notes on things like output and error handling. I’ve read your comments to judge both communication and humor.
I might not say anything on that first day — but I’ve already learned a heck of a lot. Let’s talk about acing the initial manager review.
There’s a Philosophy?
Every operating system has a philosophy. Most are not said outright but can be seen through observation. Understanding and leveraging that philosophy helps turn a mediocre programmer into a star one.
As an example, the Apple philosophy can be expressed something like: Integration is beauty; sleek and understated. All of the hardware pieces of any generation share a single design aesthetic. Both third-party applications and apple branded apps are beautifully integrated into a cohesive environment. This philosophy offers insight into Apple’s decision to leverage a walled garden approach to the iPhone ecosystem.
A programmer coding for apple products would therefore be wise to pay particular attention to the nuances of the user experience. Users will expect the UI to be visually similar to the environment. Overt crowding and vaguely named buttons will be cause for rejection by users. The placement and usage for standard functions that exist across many programs should be replicated. Doing something new may be more efficient behind the scenes, but in the eyes of your user base, you will have broken the philosophy. Your program may be functional but will not be considered “apple-like” and will likely be rejected by the intended audience.
Unix is unique in that the philosophy was actually outright baked into the initial design. Ken Thompson and Dennis Ritchie along with a team at Bell Labs designed an operating system from scratch. The principles are simple and universal.
The ideas of the Unix philosophy were expressed by a lot of people, then codified and expanded upon by Eric Raymond in The Art of Unix Programming. These are the rules as set down in that seminal work:
- Rule of Modularity: Write simple parts connected by clean interfaces.
- Rule of Clarity: Clarity is better than cleverness.
- Rule of Composition: Design programs to be connected to other programs.
- Rule of Separation: Separate policy from mechanism; separate interfaces from engines.
- Rule of Simplicity: Design for simplicity; add complexity only where you must.
- Rule of Parsimony: Write a big program only when it is clear by demonstration that nothing else will do.
- Rule of Transparency: Design for visibility to make inspection and debugging easier.
- Rule of Robustness: Robustness is the child of transparency and simplicity.
- Rule of Representation: Fold knowledge into data so program logic can be stupid and robust.
- Rule of Least Surprise: In interface design, always do the least surprising thing.
- Rule of Silence: When a program has nothing surprising to say, it should say nothing.
- Rule of Repair: When you must fail, fail noisily and as soon as possible.
- Rule of Economy: Programmer time is expensive; conserve it in preference to machine time.
- Rule of Generation: Avoid hand-hacking; write programs to write programs when you can.
- Rule of Optimization: Prototype before polishing. Get it working before you optimize it.
- Rule of Diversity: Distrust all claims for “one true way”.
So Let’s get down to how I analyze your code using these principles.
Modularity, Clarity, Composition
As a manager, I look at how you write code with an eye towards the usage of development time, not only on this particular project but on the ones going forward. Are your programs clean and thoughtful? Have they been rebased when necessary?
Modularity shows me that as a programmer you value your time and effort. If you take a little extra time in the beginning to make something modular, you can reuse it later when the business demands change. You can swap it out easier when necessary. It means that you are lazy in the best way — choosing to spend time designing once correctly rather than kludging it constantly.
Clarity is essential. The best-designed programs are easy to understand and maintain. The fancy might LOOK impressive, but clear will be more secure and easier to troubleshoot later. In a production emergency, it is clarity that will cut downtime.
Composition means that every program should be designed to take both input and output easily. As a manager, I take it slightly different than the standard “use simple text files” often attributed to Unix. What I want to see is that you understand where the input is coming from and going to, and design with that in mind. For example, composition needs for a GUI (Graphical user interface) are different from a program designed for backend processing. A GUI must be designed with the human in mind. The expectations for input and output should be clear to the new user with no experience with the interface. A backend program needs to take the ultimate destination in mind and ensure the data is passed in such a way that the target can change but the program is still valuable. This helps assume the portability of your code when infrastructure changes and dramatically increases its value.
Separation, Simplicity, and Parsimony
During the initial inspection and evaluation stages, these three rules lead to enhance security. Like it or not, security is now a huge part of the job for everyone who works in computing. Keeping security in mind from the very initial design phases is essential.
Separation of policy and mechanism means that neither is rigid. As a manager, I can utilize code designed in this manner in a development environment to test new policies and procedures and check for unintended effects. It also means that a change mandated by one does not necessarily mean that the other will have to be completely reworked. This again allows my team to function more efficiently and free from unnecessary stress.
The simple solution is often the best one. Designing something cool that will impress other developers is awesome for the ego, but awful for the production maintenance team. Keep it as simple and elegant as possible and make everyone’s life easier.
Parsimony means to keep it as simple and small as possible. Complexity hurts maintenance times. It means you will spend far more time debugging than you would otherwise. Generally speaking, developers chasing a bug deep into spaghetti code tend to be grumpy. Cranky developers make my job harder, as do cranky execs who do not care that the code is complex and impressive looking if we cannot keep it working.
Transparency, Robustness, and Representation
Transparency comes in different forms in coding. I need to be able to see what your programs are doing and why. This means talking to logs appropriately, checking the comments. If the comments say “See George for details about why” then I have to think that George doesn’t want anyone else to touch his code. A comment like that means I’m going to take a close look at the coder and see if he has other problems working in a team environment.
Robustness in the initial look-over by someone like me means that your code is designed for unexpected inputs. People and other people’s code will do unexpected things. There’s a great XKCD comic that illustrates this perfectly
Representation…stupid and robust programs can be utilized in other places. If the data takes care of the complexity you have more maintainable and re-leverageable code. If I look at the design documentation and see that the specs call for simple data I will have concerns. I will start looking into the architect’s other work and see if there is a pattern. We will likely have a meeting so I can understand why this was necessary.
Surprise, Silence, And Repair
All three of these rules work together to make how we as a team can troubleshoot easier. If you do the least surprising thing in designing your interface, users are less likely to surprise you. This is of course audience-dependent, so knowing who will be using your program is critical.
Silence. Blissful, blissful silence. I once inherited a programmer whose code originated 4G worth of log files in a half-hour. It wasn’t in debug mode. When it actually HAD a problem, those logs were almost useless because they detailed so many trivial things that sifting through them was a herculean nightmare. Ensuring your code says what needs to be said with the option for more in a debug is essential.
Repair seems like the opposite of silence, but it’s really not. Although a program can try repairing when things go wrong — restarting a service for example — it sometimes just can’t. The bug traces at the juncture of that failure are critical. I want as much as possible during that moment. When I look in your logs, some failure is expected. We can’t control everything. What I want to see is evidence that you are handling it gracefully.
Economy, Generation, and Optimization
Developers are expensive — and they should be. They provide an organizational unit with the tools they need to work, with the product we sell. Their time is valuable. Economize your time by allowing the machine to take more of the load. I will look for signs that you are perhaps optimizing to the point of cheating yourself. It’s fun to do of course, and I’ve set up competitions for developers who can best economize a specific piece of code with prizes and stuff before. Bragging rights are awesome. BUT, when it comes to production always remember that you are valuable too. The machines are expensive heaters without developers.
Generation is one of my favorites. In the traditional sense, it means making programs to write other programs, like using a makefile generator. To a manager, it means automate everything possible. I like programmers who are lazy in the best ways. Why hand-hack all the things when you can automate and make life easier? It also shows initiative and attention to detail. A programmer who routinely looks for ways to make his own life and by extension, his team's work easier is a treasure.
One of my favorite employees once told me he was talking to someone in the breakroom who mentioned they were going to have to be in the office to do a weird thing they did once a quarter. By hand. We looked into the process and worked with that team to automate it. My employee who noticed the other team members complaining over coffee about losing a weekend generated a lot of goodwill with their boss.
Just like in human ecosystems, computing ones may require diversity to function correctly. If your program has a string of greps to get a specific detail out instead of a single sed statement for example, we’re going to have a very pointed discussion at some point. I have had that in real life and the discussion was as unpleasant as the code.
There is no one true way in computing. Just what’s best for a specific situation balancing all the variables. Show me that you can recognize and leverage this and I’ll be more impressed.
- As a manager or consultant, I’m looking for how you think just as much as I’m looking for a specific skillset. Skills can be taught after all.
- Knowing the philosophy behind an operating system can give you insight into what the users expect
- Inspecting your code can give a manager or consultant great into you.