Taking it one step further. Noticing how you — yourself — get stuck is a superpower. But it's hard...really hard.
When I get stuck on troubleshooting an issue, I can sometimes fall in this trap that my wife calls the "blackhole." I obsess over it. I cannot rid the problem from my mind. My 2.5 year old even sees it in my eyes ; she'll glance up at me, wondering where I am.
Before reaching this "blackhole" state, I can start to feel when I get tunnel vision.... at which point, I distance myself from the problem.
Hands off the keyboard.
Go for a walk.
And almost EVERY damn time, I'm able to solve the problem easily. Just needed a fresh pair of (my own) eyes, a moment to get "unstuck".
I learned to do this as well after many late nights of making no progress, only to basically solve the issue in the shower or on the way to work the next day.
Sometimes grit is just NOT the answer.
There are a few things that make working ok if not delightful:
- generating ideas to try
- having an idea of the space covered
- keeping track of progress (even a well marked dead end feels good, it's done work) .. bookmarks in a way
- placing little context notes on bookmarks so when you jump in you're ready to plug your mind in more easily
- crafting a bed to try an idea with very low friction. Take a good amount of time to devise your bench/lab and then iterate smoothly.
- all of this with the notion of quickly converging toward what's good and trim what's not
I'm failing hard at it right now but I still believe it's one good way.
I think we mull over things when we sleep and wake up with answers... as long as we don't let them dissipate like a dream.
related and interesting - the sleep doctor david walker mentioned was that when we're learning something physical skill, sleep causes lots of sped-up simulation, and we wake up better at the skill.
At first I would spot potential missing pieces in the UI designs as they were proposed and would work with PM and design to come up with workarounds. I did also notice that PMs like to set up meetings to go over them, but often the specific details don't have a massive impact on the actual usability, but still a decision has to be made.
In the early stages, so much of the product design is hypothetical to everyone. Even though you could drill down on specific details, nobody really wants to, unless you're the engineer who has to implement it. This often means it's hard to communicate precisely the design issue you need to address (and often, it's "only" an issue because the implementation has to choose an option).
So, what I eventually would do over time was just work as far as I could until I had a concrete issue I could demo and explain easily to PM and design. Before I'd bring up the issue to them, however, I'd come up with a couple of best-effort solutions. (Not completed, although sometimes I could hack something together.) Usually I'd prefer one solution over the other. I'd present both options and give enough pros/cons to show why my preferred was better, but I wouldn't tell them necessarily that that was my preference, just the facts about what you get with it over the other.
More often than not, product and design would just go with my recommendation. It's true that they really don't care about a lot of nitty gritty details, and often they have bigger fish to fry, so it's a great way of making progress.
Obviously, there are some tricks to how you present the pros and cons to ensure you get your way, but obviously as a senior member of the team, you need to do what you think is best of the team and overall product.
The slowest-to-ship engineers are the ones who refuse to do a bit of design thinking or copywriting when they hit the inevitable unspecced case and instead think "not my job!". It really is your job to find all of those cases, but going a bit outside your domain to suggest the simplest solution (usually by coding it up) rather than spinning up the meeting merry-go-round is going to make you 2x more valuable than the engineer who just gets blocked.
And a lot of those orgs do 'spinning up the meeting merry-go-round' as a baseline.
I would love to find solutions, run them through other developers to make sure it won't be a disaster to maintain, and present them. But more often than not, anything beyond 5 minutes of investment isn't worth the personal time investment given the organization. There are just too many hurdles.
From my experience, most developers are still treated like idiot savant children capable of doing the one thing the 'helicopter parent' managers can't do.
If the person who wrote the requirements could formulate them precisely, they might as well have done it themselves in code rather than as requirements.
As a coder you just have to get used to it. Your job is to fill in the blanks so the higher ups can focus on the big picture.
This is why iterative planning (agile) has become so popular. You implement the most important use cases first and from there go through the edge cases together.
This leads you to another sort of stuck, though. When an engineer needs help, but everyone who could help is too busy with their assigned tasks.
I've been there. It sucks. You end up calling it a "blocker" and then managers get involved to unblock you which leads to resentment from the people/teams who were told to drop their other important stuff to help you, and then they half-ass it and it doesn't do much good anyway.
Then again, this was when I was at the large org whose chart in comic form has all the teams pointing guns at each other.
What it looks like practically is a team member whose tasks start to slip, mutate, and start to get called done without anything actually delivering the goods. It takes a supportive team or an active manager to stop and recognize what's happening.
Depending on the individual, either ego or fear are the primary drivers of the action and while everyone has their own demons to wrestle, those who make great contributors can recognize their demons and take steps to confront them. Mid devs often don't, can't, or won't.
But... if your manager is displeased with most ICs for brainstorming, considering edge cases, researching possible solutions, refactoring, helping other people, testing, and automating... you should probably consider working somewhere else. These are all things the industry does too little of, and that my company puts significant effort into encouraging and rewarding. They are also important steps in growing into (technical or people) leadership roles. And they are nowhere near the top of the list of things that people waste time on.
This isn't getting stuck, the "last 20%" of a project takes 80% of the time. This is when you start to get the REAL requirements.
Then years later I learned that asking too many questions early on that people don't know the answer to gets me a reputation of being "awkward", "negative" or "not a team player". It's not "agile" to properly understand a problem before trying to solve it, apparently!
These days I limit the early questions to ones on which fundamental architecture and technology decisions rest. My estimates incorporate an "unknown unknowns" line.
Self driving cars is one of those projects.
All problems are like that; the difference for high-value problems is that working on the tail is worth doing, because the problem is high-value.
Sometimes when you're rebuilding the entire world its good to get distracted with jumping into some firefighting (even when "not on call") to get the dopamine hit of fixing a problem and being the goddamn hero.
Then you can go back in two or three days or something to being Sisyphus.
As the currently top voted comment points out that sometimes going off and doing other things can also help "unstick" you when you're feeling overwhelmed and burned out on one particular problem.
It is actually kind of annoying to have a manager that ALWAYS wants you to be not distracted and ALWAYS perfectly focused on whatever is your top priority. That just gets exhausting after awhile, even if you technically agree that's the highest priority thing you should be working on at any given time.
This has happened to me many times.
When you get questioned about "why isn't this done yet? $previousDevX said it would only take a day!"
... what words/phrasing can you use that don't - implicitly or explicitly - 'blame' your predecessor in some fashion?
And as @ervine pointed out, there may be times when I'm the predecessor, but was hamstrung by time deadlines earlier and now have far more debt to unravel than existed 6 months earlier. But even then... while I am the predecessor, someone else made the decision to cut my effort short earlier, and we all still live with that decision now.
I turns out that usually (not universally!) the problem isn't that the previous person did a bad job, but rather that they made a set of tradeoffs that made sense at the time, and make less sense now.
Or it could be that you work with uncharacteristically incompetent engineers, but that's not the first place to look.
And the tradeoffs did not make sense. This was a simple case of bad normalization - a missed many to one relationship. It just so happens that it happened to be a relationship at the center of a very large platform, and is baked through many services. And without fixing it early-ish, we'd be fighting the schema for the next 10 - 20 years and creating unmanageable complexity in the process, all the while making it harder for ourselves to eventually fix it.
So I'm just pointing out something factual. Sometimes making sure something doesn't happen again means calling a spade a spade. If that means pointing out a mistake, then we absolutely should.
There is almost always a way to work around something. "Architecturally sound" is in the eyes of the beholder, and unless you're building the next Google, a sub-optimal solution may be perfectly fine. That's what we're paid the big bucks for: to develop a solution, one that works "good enough", without having to constantly rewrite... sorry, "refactor"... the entire project.
This isn't always the case though. Sometimes the code really does suck!
But Sloppy gets promoted while Stuck gets a "meets expectations".
The key is in knowing when it's ok to be sloppy.
How Do Individual Contributors Get Stuck? A Primer (2017) - https://news.ycombinator.com/item?id=21169212 - Oct 2019 (83 comments)
The more experienced a person is in the team, more time is spent on enabling others, more time spent in meetings, process related stuff etc. I don't say this is a bad thing for the team's goals, but the personal growth and tech exposure will be limited. Overtime, the person will become a star in that team or organization, but may lack the skills in demand outside the organization.
I think staying close to latest techstack is super important for an IC for a longer career outside their current organization. That either means dedicating few hours a work on personal projects in latest technologies, watching YT, tech/how-to videos (YT, Udemy) or moving every two years to a new team.
- Working on something that requires a complicated, flaky, manual test setup that is resistant to clean automation (e.g. involving hardware).
This is how I stay on target and finish things. Perfection is only a justifying set of sweet lies that prevent finishing.
Until a few years ago saying and writing "programmers" on forums like HN was still prevalent, and then, after a certain moment, I started seeing "ICs" more and more.
This article did indeed confuse the two (probably because the author manages programmers but does not program herself), but they are independent concepts. All combinations of IC/not IC and programmer/not programmer exist.
But now, unless you really really are part of that team, you are an IC. Programming, by nature of what it is and who does it, always had a bunch of IC's, but now the phenomenon is more clear due to remote (which is something I recommend a lot of people on here thing about as they design their career).
Hehe, that's totally me. That one is really hard, though, because it's also arguably my job. Keeping other people unblocked is the best way to accelerate the team's overall output.