Expectations of professional software engineers
adamj.eu
adamj.eu
There are certainly some valuable concepts - but the presentation is fairly incoherent (including the video of the talk he gives) and not particularly helpful.
Many of these items are utterly unrelated: Some are fairly specific to gaming (profiling/memory layout/timing) some are basic professional expectations (I can schedule my time well). In neither case is there real advice for people who actually struggle with some of these areas.
My item number 51 would be... "I can articulate my point in a more compelling manner than an incoherent collection of 50 things I don't like"
He’s writing a list as part of his imaginary shower argument with his boss and coworkers as to why they are all inferior and he’s perfect and why all the problems they are facing are easily attributed to his list of 50 points of things he feels he does that they are failing to live up to.
At least that’s my take away.
Mind that this instinct was born from prior experience with my own imaginary shower arguments.
Put differently, something you consistently find when you postmortem incidents where people have lost their SA is that they thought at the time they had full SA. They only notice they've lost it when things are clearly going downhill.
So it's important to regularly re-ground yourself with reality even if you think you don't need it. That's a critical component of maintaining SA.
That gets swept under the rug far too often.
This list makes it clear that communication (of designs, of status, of workarounds, etc) is vital for the professional software engineer.
And it's showing. There is so much emphasis on communication, people started equating quantity to quality. "Just talk more, that's what great communication is about" wouldn't be an observation too far from the truth.
Far too little is invested into researching what makes quality communication. It's just the same old rational arguments against rational arguments, day in, day out. For a field entirely about managing and sharing information, be it to machines or to people, that's pathetic.
If people are so certain it is better and believe it is important, let them stake money on it and do research. Until then, the cat is both dead and alive.
Clear lines of communication
Culture of communication
Strong vision and storytelling
Open discussions and inclusive of disagreements
Managing "up"
etc
Communication is hard.
> 6. I have a Plan B in case my solution to my current problem doesn’t work.
> 9. I can clearly articulate unknowns and risks associated with my current problem.
These rules imply one of 3 things about the author:
* That author only encounters problems that have been fully solved before
* The manager gives zero weight or value to discovery
* The manager expects the whole project to have been fully specified before starting
Yikes, that's toxic! I think it's important that engineers have the mindset of understanding the problem, but that means that figuring out the problem is part of the work! Which then means that engineers should definitely have periods where they don't understand the problem, where they don't have a Plan B yet, and don't know what the unknowns are, because they can't know what the solution will be until they've started the work.
It seems that the author has never encountered the "research" side of R&D.
Point 1 is a prerequisite to points 6 and 9. But once you’re ready to start actually building a solution, you should absolutely have an understanding of the risks and a Plan B in case your solution fails.
Nowhere in the article does it imply that you can fully understand a problem without putting in the work. The difference between juniors and seniors that the article is highlighting is that juniors will jump into implementation without knowing these things, while seniors will take time to do some research and figure these things out first. Usually, if you’re senior, you should also have the experience to do so quickly, but that’s not always possible.
To define terms, “the problem” is the issue faced by the client or the customer. The task isn’t the problem. A team should tackle tens or hundreds of tasks while still learning to understand the full problem. This is the motivation behind iterative processes like Scrum.
The author’s message is that if you don’t fulfill all 50 requirements _at all times_, you don’t even deserve to be a software developer (not even a junior). I disagree. I think I get the message that these rules are trying to send, but I think they are, as a whole, unreasonable in a professional, business environment. Everyone should be a product engineer, but being product-focused necessitates speculative activities that exist for no other reason than figuring out the boundaries of the problem being solved. And those activities need to be repeated as the problem is being solved, to evaluate if the problem is correctly understood. Someone, whether that’s a junior or a senior, needs to be spending time doing things that aren’t articulateable so that everyone else can articulate exactly why they are working on their current tasks.
As I become more senior, I’m starting to appreciate all of the tasks that don’t go onto the sprint board and aren’t articulateable. They exist because I need to know enough about Product’s or Account Management’s job to communicate with them, and I won’t know what exactly “complete” is until I’ve reached completion on those tasks. That’s part of the job, and I reject any list of rules that leaves no space for those activities.
> 1. I can articulate precisely what problem I am trying to solve.
You can read this in multiple ways, but I'm reading it as: "I'm not participating in the process of figuring out which problems we can solve. I will only ask for clarification of your intent, never try something on my own."
Periods when engineer don't understand the problem should be spent on analysis of the problem domain. "Now I am working on defining the problem domain" - is an activity to work "I don't understand the problem" task. During that period probably zero code will be written.
> That author only encounters problems that have been fully solved before
He doesn't, otherwise there would be no talk about "plan B" and risks. When you actively write a project code, you should know that solution is possible. Having plan doesn't mean "problems have been fully solved before". You may have POC which doesn't end in resolution, but it should be clear what is POC for and a failure is possible outcome.
"No one has ever solved this problem before and I'm not sure where to start" seems like an important unknown/risk to let your manager/lead know about. Likewise, the backup plan can just be "we scrap that feature" or "we solve a much simpler problem". The point is to be deliberate about what you're doing and communicate potential setbacks.
IME, finding the problem is almost all of the work.
Once I can reproduce an issue, and trace it to its genesis, it's as good as solved.
We have a problem where there isn't ever a mild criticism or offering a different perspective. Just because you don't see the world your way, doesn't mean that others are toxic.
I think this is serious problem and should be reflected upon. Sometimes to push your perspective, it starts with considering other perspectives with good intentions. May be people will listen to you.
The plan B can be "The boss cannot tell me what they want in a succinct way, and/or I am not confident what they want, so I will make various suggestions and get them to choose an option."
The unknown risks - all developers intuitively should know this unless they are very new. Stuff like "this will work, but not effort is going in to how to scale this up later", or "this requires digging up some old code no one has touched for ages, which could explode the time estimated if it is hard to understand that code or refactor it".
Number 1 should not be controversial for vast majority of IT. If you cannot articulate what problem you're trying to solve, you won't know when you're done or how to approach it or what it's value is. Anything from scope creep to underfunding to business mis alignment are classical dangers of not having #1. (note it does not read "I know exactly the specific solution and implementation details". Just says "understand what the heck you're trying to accomplish", which I would expand as "understand and agree")
#2 I view tactically and or operationally. It's good, when choosing a tool or approach or algorithm or vendor etc, to know what some alternatives may be. Presumably, you consciously or subconsciously did that work anyway during solutioning or POC or just brainstorming phase.
#3 is basic project management. Articulating risks is crucial. Ideally the developer can do it but if not, for love of all that is unholy, somebody should :). And you should be able to articulate some key unknowns - e. G. I don't know the performance of this yet to be developed application until we get to performance testing.
Plan Bs make sense for external dependencies, but for internal work they imply your current solution has feasible alternatives, which is often nonsensical.
1) Are you solving the problem that someone (your customer / manager / stakeholder) wants you to solve right now? what makes you think the thing you're working on is the priority, have you checked with someone or got convincing data
2) Are you taking longer than expected? if yes, why? What's a practical solution now and for the future so everyone remains happy? If no, why do you think so?
3) Are the people in charge of your future happy with what you've delivered? How do you know and what's the reason if they're unhappy?
4) If there's a disconnect on any of the points between you and the stakeholders, what is a practical solution that you can implement it quickly?
5) Are you knowledgeable enough that people can rely on you to solve their problems in the most practical manner?
My product manager was fired a while ago and no one has replaced him formally yet. A C-level guy is micromanaging my team's work now and he sucks at it. I really miss being able to push back on these conflicts.
My response is always that I’ll try, and we’ll see which one ends up half-finished on Friday. This either gets them to pick one, or assume everything will be fine until Friday, when it blows up in their faces.
I don’t think I’ve ever had someone (even the manager) blame it on me for some reason.
I'm confused. The blog post is written by Adam Johnson. Are you referring to Mike Acton or Adam Johnson?
I never heard of Adam Johnson before this HN post. From his books, he appears to be an expert in Django. Yes, I agree about Mike Acton and his ideas around Data-Oriented Design. It sounds like a very interesting approach to programming in a resource constrained environment.
> It sounds like a very interesting approach to programming in a resource constrained environment.
It's more of an approach that is maintainable and straightforward, and only coincidentally (well, not really...) also straightforward and fast to execute.
That seems like rather a low bar, compared to items like "I can articulate how all the data I use is laid out in memory."
I'd prefer to live in a world where a professional software engineer was expected to write documentation, and expected to be competent at it.
That's not a high bar, it's an arbitrary hoop. It'd be like saying "I always know which processor cache my variables are sitting in". In modern languages it may be literally impossible to look at a block of code and know what's sitting in the heap vs. on the stack, and the heap is often broken into many different components only fully understood by the compiler/interpreter/VM writers. We want to abdicate responsibility of this kind of memory management to the interpreter, just like we want to abdicate responsibility for handling processor cache levels. If you can articulate how all the data you use is laid out in memory all the time, you are majorly micro-managing the runtime.
Agree with the documentation thing though.
Now, it's possible to argue that writing performant software is not important. The prevailing modern sentiment definitely seems to be "The compiler / interpreter takes care of that". But given his track record of delivering high performant running software, and the trend in computing towards sluggishness, I'm trending more and more towards his camp, than the "don't micro-manage the runtime" camp (which is starting to feel more and more like a thinly-veiled "I don't want to have to think about it").
Edit: A summary post he wrote as a source https://cellperformance.beyond3d.com/articles/2008/03/three-...
The quote I'm arguing against is "I can articulate how all the data I use is laid out in memory." Indeed, writing performant code is not important, most of the time. It is critically important a small amount of the time (actual percentages heavily dependent on the type of software), and yes, in those times, understanding the architectural realities of the hardware is somewhere on the list of things you need to understand to do so, just below a solid understanding of complexity analysis, a wide knowledge of useful data structures, proper design of queries and use of indexes (if relevant), etc. A good software engineer does not say "I always know exactly how all my data is laid out in memory", they say "I know when and how to care about that, and the rest of the times I ignore it." Just like they do with many, many other concerns. Anything else is just premature optimization. The most important problem solving skill by far is knowing what you can safely ignore.
Unfortunately, in practice, it's not possible to be oblivious of the layout of data in memory if we want to write fast code. The CPU/memory speed disparity graph [1] shows the new reality for programmers: the slowest part of a program is bringing data from RAM into the CPU registers. Fortunately, modern CPUs have very fast caches that help amortize this cost and it's the responsibility of the programmer to organize data to take advantage of that fast hardware—the compiler cannot do it. That's why two functions, with the same algorithmic complexity, and which compute the same result, can have an order of magnitude of difference in performance between them [2]. The famed sufficiently smart compiler that can do those transformations does not yet exist as far as I know.
[1] https://gameprogrammingpatterns.com/images/data-locality-cha... [2] https://play.rust-lang.org/?version=stable&mode=release&edit...
"I can articulate how all the data I use is laid out in memory"
super basic. It's something that you just know by instinct/reflex at any time.
I work on a team now where we get huge scopes of work and a couple people will tear that work down and would answer these questions as they do so. However, most teams I've been on deal with far more interrupts than the team I'm on now does. Those interrupts are lemented but justified by the business and definitely impact an engineers dedication to a given projects. Interrupt driven work is a sort of split brain problem that I think gets in the way of answering these kinds of questions because it removes the time that an engineer would otherwise spend entrenching themselves enough to know the answers and problemscape.
which is totally fine, most of those things don't need to be done explicitly. (as such they take less time than many commenters seem to think they would.)
being able to articulate something doesn't mean that you've taken the time to do so. just that you've generally thought about your task enough before starting it that if your boss asks you that question, you can produce a coherent answer in a timely fashion.
I don’t believe this is possible in an average company.
If these were actually the bar, everyone in our company (including me) would get fired, and nobody would ever get hired again.
Too often I see devs go down some deep rabbit hole to solve a problem no user has ever had, and I wish they'd have talked to me first about it.
But the author of this article could have generalized a lot here, many of these could be summed up by the (admittedly less interesting) "I know how to communicate clearly and do so frequently with my team."
Where is the company that gives engineers enough freedom to satisfy all 50 points?
I also realized, I'd put a small asterisk on "I have recently profiled the performance of my system," as well. I would expect that an engineer would do at least some minimal profiling of their code in order to make sure it's not too slow in itself and doesn't excessively slow down any calling code, but for the most part, with a running production system, it's generally safe to assume that performance is good enough unless you've been shown or told otherwise. And I think that all still fits into the spirt of the expectation as well.
So that's not what they're advocating. Though I think they're 100% wrong on that point, and most managers would probably think so too.
Same for single threaded vs parallel etc.
I hope this guy has a complimentary list of 50 things for other roles.
It's appropriate to put this one first because it shows up in so many of the problems that follow.
Easier said than done when there's a deadline pistol pointing at your head. You gotta get stuff done. Show progress. Writing any kind of specification is just a slippery slope to Waterfall, geez. There's no time of any of that namby-pamby talking to and watching users BS. They don't know what they want anyway! Real developers ship!!
"I can articulate precisely what problem I'm trying to solve" is not just on that person. It is a function of their collaborators – product/program/engineering managers and other engineers around them.
If you are in a culture where it is acceptable to send tasks at each other without much context, and with harsh deadlines, and with a perf management system that rewards execution under such conditions, then you will get precisely the opposite of someone who can articulate what problem they are trying to solve.
In fact you will get a culture where asking questions for deeper 'why' understanding will be seen as disruptive.
> If there’s something wrong at work, don’t put off talking about it.
> I am not actively avoiding any (professional) conflicts.
> If you’ve noticed something is going wrong, whether technically or communication wise, get those conflicts out in the open. Letting them stew never helps.
This requires a prerequisite of trust which I think is more of a rarity than commonplace. People will speak up about stuff, but not all stuff.
IMHO it makes sense if Plan B is much simpler, but not as efficient as Plan A (remember, this is a game developer, everything is about efficiency). You build Plan B is a prototype, and could still fall back on it (and iterate on it) if Plan A fails.
If Plan B is more complicated than Plan A, doing it first sounds... dumb.
The connotation with plan B is you do plan A, then if it doesn't work, you do plan B. If you are supposed to implement plan B first then really plan B is plan A.
More complexity raises the cost to support and develop new features in a non-linear way.
If you do features A, B, and then C; feature C might seem to be the most difficult. But if you do A, C, and then B; feature B might seem to be the most difficult. If you manage complexity poorly in features A, B, and C; then perhaps feature D is too expensive to ever accomplish -- not because it's inherently difficult, but because it's difficult given the complexity already present due to A, B, and C.
To me, this is the fundamental challenge of software engineering. Other kinds of engineers must deal with complexity as well, but it's somewhat more contained due to physical constraints. Software complexity is unrestrained.
I think anyone should be expected to write a simple bug report, with reproduction steps and expected versus actual result. There are a lot of people out there who don’t do this simple, necessary task well!
For example, my new data management system can also do many traditional relational database table operations. If you want to do fast analytics or queries, then it can do it better than the competition. For basic stuff, other RDBMS solutions will surely get the job done; but if you want to build a pivot table against values in a 10M row relational table then this is the tool you want: https://www.youtube.com/watch?v=2ScBd-71OLQ
I never actually attended college in Florida, but all my experience on this is from exactly FU!
Interesting cross-over with Mark Burgess's Promise Theory, where a promise serves somewhat as a single discrete expectation.
You can't pre-solve problems you are unaware of but in most software engineering two problems are very predictable:
1. The system will have to handle more load in the future. 2. Someone will eventually want to change the business logic.
It is wise to write software in a way that you are well positioned to resolve those problems as they arise. When I use the word future-proofing in my day to day work, this is what I am referring to.
This kinda stuff always reminds me of someone making a PR for something like a react component that lets you choose a time zone. It can be a 100 line simple thing or it can be an 800 line monster with files for typescript types thorough tests, etc. I prefer the former but I feel the author would expect the latter.
which of those besides #3 requires day-to-day interaction with another engineer?
and i'd expect #3 to fall out of sprint planning, or just talking with your coworkers about your work.
On the other, I can easily imagine the reaction from most project managers if they'd asked me put together an estimate for fully achieving all of these on any given project. Some of them would involve sitting in on business strategy meetings, which is a pretty far cry from the level of involvement I generally get! It's sometimes hard to even get hold of representative hardware to test on.
At this point in the list we start to diverge from what engineers/developers are allowed to know in the modern enterprise. Here is where we start to get push back from the Program/Product managers, Scrum Masters et al. To proceed further down the list is to remove the added communication channels between engineering and the business.
https://medium.com/the-mission/how-to-release-your-expectati...
Now what are everyone's expectations of Mike Acton? If someone sends me an email like this before I'm about to start on a job -- I just know he must be feeling some pressure.
What?
1. Logical positivism is not a proven perspective, it’s actually mostly rejected. How do you falsify “I feel angry”?
2. We aren’t doing science. What’s the hypothesis for “I’m adding a close button”
If you are building crud please don't get out the profiler unless you have a performance problem. Even then, if it's crud you're probably not going to look at memory usage first.