A lot of companies aren't trying to hire the "best" programmers. Places like Amazon won't let engineers use highly-skilled techniques anyway.
The high-profile RTO places tend to hire in bulk for programmers that will do as product tells them. Weeding out people who value quality over conformity is a goal.
I work with an Amazon engineer who has been working on storage systems since 1990 (NT kernel) and is an absolute wizard. He could probably write a durable concurrent B-tree in an afternoon.
I think the argument is whether or not we admit we are having these effects and take responsibility for them, we are doing them.
I personally find that telling people exactly what I intend to do makes it more effective rather than less. But in a field where we can change people's behavior by making a button orange instead of blue or presenting a form in one page vs three, I find it impossible to pretend that one of those is a neutral choice.
Instead, I focus on what it is we are maximizing for, and how people feel about the experience. I push my companies to choose patterns that help people feel secure & in control, leading to predictable outcomes that align with what they actually expressed wanting. It means we are collaborating with our users, even though we could have used those same techniques to make them feel more anxious, spend more money than they intended, or buy things they didn't actually need.
I believe the OP isn't arguing that the language shouldn't have the problem, but rather that we shouldn't be relying on the language to try to solve this problem.
By hiding the complexity of multi-threaded programming behind these facades, we let people write multi-threaded programs without understanding what it is doing. That in turn leads people to believe they don't need to understand parallelism to write thread-safe programs well, and it simply isn't true.
Companies don't want to pay for actual expertise, so we are all pressured to do things we don't understand. Languages can enable us to succeed some of the time, but they can't make distributed systems actually simple. The errors that pop up as a result are a predictable consequences of relying on under-trained workers without the resources we need to do our jobs well.
Most of the world shouldn't be writing services that saturate their network links (actually, no one should: if you don't have slack in the system, it becomes incredibly error-prone. But even running at 80% saturation, most people shouldn't be writing those services.)
There are a small number of very large companies where their architecture is based on that sort of thing. But in most cases in most places the right approach in that situation is to ask, "why is this a thing you think you need?" And then to either inline the service or employ horizontal scaling strategies instead of trying to stuff more cycles onto one network card.
I do agree that these language choices are very likely a symptom of the misuse of service architectures. People are treating services like objects (or worse, Singletons) that live on a different machine, relying on the network stack as their interpreter. It makes "modern" software buggy and fragile. Neither of these languages solve that problem, but they do capitalize on it.
> Most of the world shouldn't be writing services that saturate their network links
Very strange hill to die on, and feels like a side attack towards a point that you chose to ignore: namely that classic multi-threading is fragile and does not scale well. Doing the async/await thing is objectively better. I get why people don't want to admit that they invested so much in something and are grumpy that this skill is now not as needed -- I was one of them in fact, I am coming from C pthreads and Java after -- but being a curmudgeon and trying to do a torpedo attack on a discussion about multi-threading vs. async/await is something that I can't endorse.
> "why is this a thing you think you need?" And then to either inline the service or employ horizontal scaling strategies instead of trying to stuff more cycles onto one network card.
Very often false, having stuff being only on one machine with 1-2 hot backups and a load balancer is the lowest maintenance I've done on systems for all of my 22 years of career. Feel free to disagree but (1) most programmers will never work on the scale of AWS and Facebook and (2) horizontal scaling / distribution comes with many, many new failure modes.
On that note, I'd argue KISS is the multi-threaded approach. I'm maintaining a server software that is multi-threaded with plain old blocking I/O and it easily saturates a 10GBit/s link without breaking a sweat on quad-core CPUs from a decade ago.
I guess it really depends. In all my practice with C pthreads and Java threads, this code always spiraled to unholy messes due to constantly adding to requirements.
Yes, as an example, if you look at something like PostgreSQL or MySQL the code is absolutely intimidating because they use crazy data structures and synchronization techniques to squeeze out another nanosecond under heavy load. But I couldn't tell if async/await would make this any better while still delivering similar performance.
Just because your position is unpopular doesn't make it wrong.
async/await is particularly damaging because it breaks the paradigm of Javascript. That no one can draw a picture explaining it is a huge problem, and it encourages people to write callback hell code by hiding how ugly it is. Unfortunately, whether the code is pretty or ugly the massive webs of nested callbacks are still a source of massive complexity and potential failures.
I constantly see tests in the wild that are passing even though the assertions fail because people don't understand the concurrency model they are using. And at least 60% of the time there was no reason for that concurrency to exist in the first place, except that it's what the code example looks like.
> it's better to have one well-defined way of doing things in a language, instead of adding the mental overhead of deciding between one or the other
That was the hypothesis of Golang, for sure.
I think we've seen that it is true in specific contexts. It seems like it's been particularly valuable to massive teams with less-experienced developers coming from academic computer science backgrounds, frequent turnover and high-coordination projects.
I don't think that property has proven to be valuable more globally. Consistency for consistency's sake is particularly costly when the "consistent" solution has significant downsides in some contexts.
On small teams, having consistency result from actual alignment is incredibly valuable, and a sign of a high-performing team. In those contexts I haven't seen consistency itself, enforced by an outside group and especially without a way to work around it when the "consistent" approach has a reason it sucks for a particular application, be similarly valuable.
Guy Steele's talk "Growing A Language" gets into this. It's definitely worth looking up if you haven't seen it.
I think we've seen two ways languages have successfully been open to evolution:
Java was specifically designed to allow it to build on the standard library over time in fully backwards-compatible ways. It has required the central governance committee to adopt proposals, because reflection is slow and poorly-optimized, but it is a far more fully-featured language today than it was an inception without ever needing a reset. By keeping the surface area small & the strong "Everything Is An Object" paradigm in place, it has had remarkable longevity and has avoided the Python versioning pain.
The second are the "sharp knives" languages: Javascript, Ruby and to a lesser extent C++ (only because DLL hell is very real).
All three of these can be used to write software in any paradigm (including Aspects, if one is a masochist), and so let engineers invest in their own productivity. Languages where the standard libraries are indistinguishable from custom libraries require more skill and collective team alignment to use productively and safely, but also allow for solutions highly-opinionated languages can't support.
Prioritize some work you can tell good stories about in behavioral interviews.
If you have a conflict with a coworker, for example, that's something you will be asked about. Instead of avoiding it or getting louder about what you think, get together and see if you can learn what they value that it leading them to their conclusions. Echo back to them what you think it is until they feel like they've been seen and understood. Maybe invite them to collaborate on an experiment so the decision can be based on data instead of speculation, or reach out for coaching from someone you respect. Find boundaries that let you determine how you will behave, rather than trying to get someone else to behave the way you want them to. Or whatever other features of your conflict-resolution skills you want to practice.
"Technical decision making" is another common one: look for a place where there is more than one option, and figure out how to efficiently and effectively lead the team to consensus on a solution.
"Tell me about a time you saw a problem and were able to make it better" is another I've seen. Take up a thing you think your team could use more of, like tests or documentation or alerting or retros, and figure out what is making that hard to get done (one easy trick: try doing it. See what stops you.) Figure out who you need to get on board with trying something different.
If you can't get those experiences in your current role, consider finding a non-profit that needs some coding where you could have more autonomy & getting permission from your current employer to do some work there (on your personal equipment.)
If you don't have a non-employer-owned computer where you can nearly-instantly spin up a new project in your preferred language with unit testing in place, it is going to make any take-homes you encounter harder. Make sure all your personal content isn't on the work computer, and if you want to keep your collection of reaction gifs have those on a hard drive you own.
Similarly, make sure you are connected with any coworkers you may want to stay in touch with, whether that's on LinkedIn or exchanging phone numbers.
And finally, if there are any useful generalizable utilities you've written for your current job, consider taking those through whatever your company's process is to open source them. Not only are those great things to have in a portfolio & passive networking with anyone who uses them, it means you won't have to write a similar tool from scratch and slightly differently at the next place. Just make sure they are something you would want potential employers looking at: legible code, automated tests, useful documentation, etc, and that your company's lawyers sign off before you expose any of the code.
I wonder how much of this is related to the how the executive class at most FAANG companies has give up on the goal of "tech athleticism" in favor of legibility to management.
Every non-tech company I've been at has been able to move faster than the FAANG companies I've seen from the inside.
The coordination overhead is so much lower it is unreal. You aren't forced into inefficient one-size-fits-all microservice-based architectures with O(nlog(n)) infrastructure overhead. You can use programming languages that make experienced developers productive, rather than minimizing what a new grad has to learn before they can be bullied into working longer hours.
Trying to coordinate complex features in a low-trust, high-overhead environment these companies have gone to a style of up-front planning that makes Mythical Man Month's waterfall look nimble and enlightened. With overhead so high, you can't experiment or build incrementally: as soon as one feature is delivered, you are expected to move on to whatever objective a VP has identified as the next important thing. That is if you even have time to code anymore, what with the hours of meetings each week to discuss the prose we are going to write to get permission to draw a picture that will have to go through approval before coding can begin.
Non-tech companies, the executives don't know enough about tech to want to micromanage like that. At most you'll hear from them what they want the technology to accomplish. If you can make it do that? You have a golden ticket.
You also often get to talk to your actual customers, and have the mandate to fix the things that bother them about the software. Instead of having to deliver a feature so a salesperson can check off a check box during their bakeoffs and buy a slightly bigger yacht next year, you can focus on how valuable and reliable and maintainable software is. _And the company makes more money when you do_, so they are happy.
And if you bother to calculate your hourly wage instead of just looking at your annual, well, I've found it shocking how underpaid many FAANG engineers are now that they aren't being paid in shares cruising up a bubble. When this article says "work-life balance", what it actually means is "not being expected to donate your time to your company on pain of firing."
You have a tech company boasting about the "dozens" of major features it launches each year, and then you realize that per engineer that's like one feature per 2,000 developers. Athletic they are not.
If they have severance, they may want to take some time to decompress or they may be antsy from not having coded in a week. So the answer is likely to depend on the person.
One thing that may be useful is to collect resources about programs in your state for displaced workers. For example, if they were interested in taking AI-related courses at a local college, in many states there are badly-publicized programs that could let them do that for free. Checking in on how their filing-for-unemployment experience goes once severance runs out might also be useful: it can be an overwhelming amount of paperwork, especially in states that use making it hard to get as a way to keep their spending down.
Networking can often be miserable and overwhelming, but meeting with our former-coworkers that we actually like can be fun while doing the same good things for our career. After the initial shock fades, consider hosting an event of some kind, whether that's a dinner party at your home, a trip to a local aquarium, an MMORPG guild, or a hobby-coding night at a local library (most libraries have community spaces you can use for free: you just have to ask.) Invite a mix of people you think will get along and have good conversations. Consider child-friendly events, child care, or taking some time off & scheduling during the school day if your coworkers have children.
It can be very lonely after getting laid off, especially if one had been working long hours. Building a small community of nerds who get together even if you are no longer working together 40+ hours a week can help that loss from becoming overwhelming.
The high-profile RTO places tend to hire in bulk for programmers that will do as product tells them. Weeding out people who value quality over conformity is a goal.