IDK, a sufficiently complex consumer or enterprise app winds up having big performance problems if people don't know what they're doing w.r.t. the code they write and how they connect systems together with that code. Those performance problems start out not mattering much, first it impacts one seldom-used part of the site, then another, but that chips away at users and can eventually tank the product. That doesn't even get into writing code such that it can be well-understood and modified easily later. It also says nothing about reducing/fixing bugs.
If you have a site whose performance steadily gets worse and the rate of new features steadily declines and the rate of bugs steadily goes up, then your site/app will probably not have a great future.
All of those things depend on solid code. If staff engineers who are too busy talking and building consensus such that they aren't connected with the actual programming and situation on the ground, then all the talking and consensus-building won't matter.
> a sufficiently complex consumer or enterprise app winds up having big performance problems if people don't know what they're doing w.r.t. the code they write and how they connect systems together with that code.
On those complex systems in particular the problems start long before any code is written.
A software engineer can create and understand the specs, requirements, design the system, architectural decisions, define everything about that software and data, model everything, failure, performance, operational topics, documents everything, etc. before a single line of code is written, and of course they can write good code. Then there are the coders who patch together chunks of code from Stack Overflow or whatever boilerplate they have in the company's repository. I know every coder likes to call themselves a "software engineer" but there's a world of difference between the two types.
For the first group code was never the hardest part. For the second group there was never any other part.
No they can’t do everything before writing a line of code. The design and requirements feed into the code and vice-versa over and over through the lifecycle of a piece of software.
Some architecture work and design will be done beforehand, but many details will fall into place as the code is being written, thrown away, adapted, etc.
The idea that code is mere transcription - which I see a lot in these AI discussions - is completely false. Code is a form of low-level design and is where the rubber hits the road.
The best requirements, designs, marketing, etc are worth jack if one fucks up the code. The code is the actual product.
Which part of my list was just "a detail" to be dealt with at some point in the lifecycle (but only if you're not too busy shipping features) for you? You're laying bricks before knowing if the wall's supposed to be concrete.
> Code is a form of low-level design and is where the rubber hits the road.
Sure but in keeping with your analogy tires are fungible across most cars and it takes minutes to change one if you picked the wrong compound. It takes years to properly design a tire, not to speak of everything that sits on top of those tires. By the time you actually "meet the road" you already defined to a tee what you want to achieve from every perspective and everything you do is to meet that goal, even if you have to make tweaks. You don't find out if it's a scooter or a roadster tire while working on it.
> The best requirements, designs, marketing, etc are worth jack if one fucks up the code.
Why are you mixing some fundamental things which are essential and can't be changed along the way without massive effort and risk, if at all, with things like marketing?
Do you want to aimlessly write code while chasing a target that moves randomly and conflicting because your plan was to define things "at some point"? You're really making my point with your insistence that it's all about code and every other fundamental thing is "a detail" that just comes along the way.
No part of your list was just a detail, but all parts of the list consist of essential properties and details. As I said, many of those details will fall into place when one starts implementing the core architecture.
It also matters a lot what scale one is operating at. Bigger scale will require more effort up front, PoCs, several big iterations, etc.
To give a smaller scale example, I defined a general simple protocol for two local components, picked the IPC and defined the handshake and teardown sequence. The developer defined the message contents. Reviewed together, then it was implemented. Testing showed that component B, which was OSS and had a fixed rate was sending too fast so the developer patched it to do debouncing.
Coding is nothing like changing tires. To abuse an incorrect analogy even more, the architect would prescribe the properties of the tire or even the behaviour of the vehicle and the developer would design and construct the tires/tracks/whatever either from existing parts or from scratch. Possibly going back and forth on the actual means of locomotion.
To wrap it up. Requirements, architecture and design can be changed. When implementing features I always do architecture review with the team and adapt it based on their feedback. We have rejected or negotiated requirements based on PoC or just developer evaluation.
Sometimes that doesn’t work, sure. If it’s a critical feature or there are hard architectural restrictions one puts in the dev work to figure it out and maybe this leads to a non-ideal implementation.
Fundamental mistakes at requirements or architecture level do have higher impact, but iterating and having a good arch <-> dev feedback loop is one of the best methods I know to tackle that.
To give another example, I investigated the potential implementations for a feature and prepared a list of technical approaches sorted by specific architectural attributes. The dev team wrote the code to validate them and option 1 turned out to be impossible because of platform constraints. I adjusted the architecture to use option 2.
Your comment brings ripgrep to mind. Grep is about as ubiquitous a software tool as you can get with a very clear contract on input-output and it has absolutely stood the test of time. Then ripgrep comes along, it has the same contract as grep (with I think a few inconsistencies that were intentionally tweaked for modern use-cases...and also I'm sure a few edge-cases from its design), but is significantly faster. The fundamental contract with the user stayed the same, I'm sure some of the design changed, but fundamentally the only difference is the underlying code. And that makes such a big difference that I *always* use ripgrep over grep now as do many others.
That's just one half of it: Intelligent defaults + configurability of what files/dirs to skip. That part has been iterated on in prior tools like `ack` and `ag` and `git grep` for like a decade, and ripgrep was informed by that tradition.
The other part is extreme optimizations, from I/O and OS aspects to CPU, both asymptotic complexity (from scratch NFA regex engine), concrete complexity (rust, SIMD) and ad-hoc opitimizations for statistically common uses like fixed strings...
Then there are some "product" choices driven by performance insights, e.g. no line numbering, defaulting to non-deterministic unsorted output order — these go against most programmers' intuition for "ideal tool I'd like", but turns out the speed gains are significant and what I really like is how fast it is :-)
Both usability & optimizations are described in depth by the author in https://burntsushi.net/ripgrep/, which is one of the best perf. readings ever, highly recommended.
In my experience, the parent's view and your view are an example of the divide between the Silicon Valley / startup mindset -- it doesn't need to last, it just needs to get us a paycheck so we can go on to the next paycheck -- and actual software engineering where people build resilient systems meant for humans to use for a long time.
There's a conflation too that to approach things with this level of thought and care requires waterfall design (it doesn't), so people shrug it off or resist because if you want to think carefully and design thoughtfully you can't also Move Fast and Break Things.
Ironically, we all complain about enshittification.
I don’t think anybody except those working with e.g. DO-178B or ISO26262 does BDUF.
Iterative processes are state of the art. The RUP iterative lifecycle illustrates this nicely, with a big chunk of design in inception (first project phase), but also a non-trivial amount of implementation. The design & implementation flow in parallel in the next phases.
> Because if you ever go back a step, it is no longer the waterfall model
By this definition there has never been a waterfall project. They all need to correct, adapt, or redo something.
Look, I think I get your point but you seem too stuck in some formal definition riveted with assumptions to understand the other side. If you build a house you can correct some things after the fact. You forgot a power outlet or a light fixture? You need to move or resize a window? Probably fine and even decently low effort. You realize your foundation is too thin or too small? You forgot about one room? You put the bathroom on the wrong side of the house? Not so fine and definitely not low effort.
The state of software development is so bad because so many devs just jump head first into writing code and in the end they deliver a pile of barely held together shiny bits that technically works but is a pain to modify, extend, maintain, secure, extract the expected performance, etc. All because there are 100 brick layers and not one architect or engineer on the team.
I think most people who write code are the latter and not the former. The industry has diluted the term "engineer" so much that they maybe don't even realise that traditional engineering projects are about more than just implementation work.
Each unit of work in any given feature of a Web app has been implemented 500 times yesterday alone, and nearly each time exactly the same way. I mean that’s what programming basically is right? I’m surprised these patterns that are repeated so often by developers could have been/still be automated away even without AI/LLMs.
One thing I wonder about is how applicable your statement about web apps is to something like lamps or lighting generally. How many electrical engineers have re-designed a circuit that turns on/off a light? Are EEs who wind up doing mundane engineering like this still engineers?
You don't need to be an "Electrical Engineer" to do simple design work like this.
Professional Engineers are qualified to take on more liability than just creating a design. So you don't need an Engineer to design a product, but (depending on jurisdiction) you will need an engineer to certify that your product won't hurt or kill people.
If you do a lot of design work, then you may want to hire a Professional Engineer in-house so that your company has more confidence that they will produce compliant designs with fewer iterations.
Engineers are often the best people to work with if you need to do things that are done infrequently since theoretically, they're trained in the prerequisite first principles so they can make judgments that are rooted in rigorous analysis in addition to their practical experience.
"electrical engineers" aren't usually the ones making a lamp though. If you're paying EE wages to add a light switch to an Edison socket you're massively overpaying.
Lots of things have lights on them though. I'm thinking every status light on every piece of hardware.
Edit: also, I'm not exactly filled with knowledge on new lamp design/construction, but I have seen startups/kickstarters that make new lamps that seem like redesigns from the ground up.
Aerospace engineers who build rockets do not have some certification body allowing them to be called engineers. Same with most electrical engineers working on almost everything.
If you think a government deciding who is an engineer is a *good* thing then maybe you should ask yourself why the United States which doesn't require this for the two non-software engineering disciplines has the best engineers in the world.
Really? What evidence do you have for that? Are you saying that companies like Airbus, Mercedes-Benz, Ferrari, ASML, Leonardo, Rolls-Royce, Dassault Aviation, Toyota, Bosch, Komatsu, Siemens, ABB, Mitsubishi Heavy Industries, Alstom, Vestas, Samsung, Sony, Hyundai Heavy Industries, Mitsubishi Shipbuilding etc. don't have world class engineers?
The United States has the best engineers because it pays the best. Good engineers from other places move here to capture some of that. Obviously strict licensing laws would get in the way of that.
Outside of some exceptions which don't really exist in the US (shipbuilding and heavy forging) the American companies in those industries are highly competitive and often market share leaders.
Annoyingly, the US government still sometimes does.
If you want to take the patent agent exam, your CS degree has to come from an ABET-accredited program, though many of the very good ones aren't (Stanford, CMU).
Likewise, federal jobs also sometimes seem to want accreditation but not always.
You can call yourself engineer if you feel like it, however in case it comes to some court case due to liabilities and such, there might be some issues coming up with having Eng in that contract signature.
Many here would probably say that they have never did the exam, and nonetheless use the title, which is as mentioned, not an issue as long as you don't land in court and the validation of title doesn't come up.
Also in most European countries, being an Engineer even if not professionally qualified, automatically means that the person in question took a university degree in engineering, on an university whose engineering degree was certified as such by the government organisation responsible for all engineering professions.
If you can call yourself an Engineer if you feel like it, then it's not a protected title.
"Doctor", is for instance a protected title. You can not advertise yourself or your services as a doctor unless you're a qualified and practicing medical professional. I believe some kinds of legal practices are the same.
[MIGHT HAVE INACCURATE IMPLICATIONS BUT PRESERVED FOR POSTERITY:]
In Germany I don't think that counts. "Software Engineering" as a title isn't regulated (as kcexn is asking for). The German term "Softwareentwickler" more literally translates to "Software Developer" (as opposed to "Ingenieur") but I don't see companies having problems translating that in job posts and even contracts to "Software Engineer". I've never seen "Softwareingenieur" used tbf.
Getting into Germany as a Software Engineer (for app development) is also as relatively frictionless as it gets in comparison to more-traditional engineering fields.
Verdi is the German trade union so they have to make these kinds of distinctions about which professions they can represent. Don't quote me on this one but I think Verdi represents very little of the modern "app development" software engineers. I guess those who work for more traditional German industries like auto-manufacturing can fall under their umbrella.
---
[LESS INACCURATE EDIT AND MY THOUGHTS IN LESS WORDS:]
In Germany "Ingenieur" (Engineer) is a loaded term with legal implications so "Software Engineer" is "Softwareentiwickler" (Software Developer) instead. But really this is an HR sleight-of-hand trick. At the end of the day, getting into professional Softwareentwicklung is the same in Germany as in elsewhere that calls it "Software Engineering" (and IMO is what kcexn was asking about anyway).
Well, I have been well served by I.G. Metal, by working in industries they also covered.
Also I have yet to meet anyone doing agency work, that started as Azubi, Quereinsteiger, BWL,... and would sign any document or call themselves Engineers, like it is so very common in US out of a plain bootcamp.
I don't think Software Engineers in the US would sign any documents that expose them to legal liability as a professional engineer either.
It's still not clear to me from this discussion whether the term "Software Engineer" is legally protected in Germany (or any other European country) or if it's just a cultural convention.
The distinction is basically, if a software developer started a consultancy developing custom software solutions and called the company XY Software Engineering, would they be penalized for false advertising if they didn't have professional engineering qualifications?
Your mobile phone runs on a CPU architecture designed in Europe (ARM), manufactured by a machine that only a European company can make (ASML), using a number of protocols invented in Europe (Bluetooth for example), using protocols invented in Europe to browse the internet (HTML/HTTP), based on a very long history of computer science ideas and programming languages invented in Europe or by Europeans.
Give credit where credit is do.
Having said that, I do agree that US companies tend to be better at commercializing new ideas than European ones.
For sure there are great engineers that are from Europe, I've worked with a bunch in the US, but it's a numbers game, and there's no competition there. Partly because so many of those great European engineers come here.
It's an ARM CPU - ARM is built off Berkeley RISC. ASML would never exist if not for billions of dollars of R&D spending by American chip manufacturers, much of which was directly provided.
Obviously there are good engineers in Europe. There just aren't as many as there are in the US, in large part because the US encourages immigration with much higher salaries.
It is correct that a lot of talented Europeans get educated in Europe and then immigrate to the US starting successful companies. Without those Europeans, there would be a lot fewer successful US companies.
American rules, if you start a billion dollar company in the States you're one of us :)
On a more serious note, the US awards more college degrees per capita than most other developed nations. Strict licensing requirements or not, software engineering is just what it's called here because of the many and obvious similarities between it and other kinds of engineering.
The English term "software engineer" is not a protected title anywhere, FAFAIK. However, the local language equivalent of "engineer" is protected pretty much everywhere in Europe because it was awarded solely at technical colleges and universities. The title is (mostly) equivalent to a Master of Science degree, except that technical colleges could also award it (the English equivalent being Master without field designation).
Before I retired (in the US) the organization I worked for was heavily civil engineering oriented, and they were pretty insistent that the computer folks not call themselves engineers. The state licensing board was pretty insistent too.
I was also in a consulting CE firm working in software, but had moved from an engineering position and had an engineering undergrad degree. I was strongly encouraged to get my PE so the company could advertise it, even though the PE credentials had nothing to do with software development.
I think civil engineering is the main field in the US that relies on certifications/tests for FE/PE, there's probably more I'm unaware of though.
As I pointed out above though, aerospace engineers (working on rockets/space applications anyway, IDK about planes) and electrical engineers don't need those tests. Requiring it for CEs seems like a historical artifact more than anything.
> In which countries are Software Engineers not allowed to call themselves engineers unless they are professionally qualified engineers?
I think a better question is: what is the criteria those countries use to determine if someone can use the engineer title?
In general the software industry is still in an early confused state about standards, approaches, skills, etc.
Should we be using functional techniques? Object? Both? Relational? Column store? Push? Pull? etc.
The number of ways to build a working system is enormous and we have a fad-of-the-month every 5 years which starts as a silver bullet and always settles down to be just another option for another set of use cases.
The European Council of Engineers Chambers is seeking to standardise training programmes, beginning with the civil engineering sector: https://www.ecec.net/what-we-do/common-training-framework/.
Hopefully, this convergence will extend to other engineering professions.
I agree that all those pieces are important, for sure. But it can all be undercut by a few for-loops that don't consider string re-allocations. That covers the "don't understand good code in the slightest, make big mistakes" side of things, but the other side is being able to think about the algorithm that is being run in your system (sometimes across multiple layers of code) and writing code that eeks out the highest performance from the system you're on in the programming language you're using. Also, to be clear, "the algorithm" here doesn't have to be super complicated or theoretical it can be as straightforward as assembling some data structure in response to a user's query across a few different sources. That process requires being able to write good code.
I would counter with it's easier to fix bugs, improve performance, pay down technical debt than it is to fix consensus, stakeholder buy-in, and strategic direction. So even though good code, design, and architecture isn't easy it's still the easy part in a relative sense.
I did not mean to imply that consensus, stakeholder buy-in, and strategic direction are easy, or even that they are easier than writing good code. My point is just that the code part is not easy either. I think the article's point that "if good code was easy, we'd have amazing software everywhere instead of crappy software everywhere" is a very good one. The average code that gets written is horrendous, interviewing people who are presently employed and struggle to write a for-loop makes this really apparent.
A lot of those performance issues in enterprise systems are platform specific to begin with. I’ve never seen what I’d call a high performance ERP, even when on the cloud. It’s usually poorly documented. It’s unclear when a pick list passes QA today well, but in a year with the list exceeds X items, the whole application crashes or grinds under the weight. A lot of time these things are learned via scar tissue and could have been easily prevented if better standards or documentation was in place.
I’ve used a lot of Oracle ERP products and I always comment about how poorly their queries run for a database company. It used to be thought it was a hardware issue and they’d sell you accelerator licenses, but now that I see more and more I’m convinced they just don’t care about performance. They want it to slow down so they can sell you more. That, and the feeling that when you build a platform for all, you’re building a solution for none. Meaning, it’s such generic and customization heavy they can always point back at you and say it’s your implementation that’s problematic not our platform. Sometimes that’s true, but also when I pay what I pay, I should get better performance irrespective of how I implemented it. I run a simple query often that’s basically selects all the accounts numbers and names from my chart of accounts (accounting), this is a central and core part of the ERP, why does this query take 45 seconds to return 200 rows of 2 columns wide.
Fixing bugs, improving performance, paying down technical debt all require this as well, which makes them significantly more difficult to actually implement.
That’s because fundamentally you need those strategic items to have space to do those particular detail items. If you have the best strategy and no execution, you can probably hire for that. If you have no strategy and decent execution, you are driving the Titanic into the iceberg.
> IDK, a sufficiently complex consumer or enterprise app winds up having big performance problems if people don't know what they're doing w.r.t. the code they write and how they connect systems together with that code.
I don't think you're really disagreeing with the original sentiment? However, I think you're taking a much broader view of "code" than is intended by the original statement.
In your framing, you're kind of confounding code with architecture. Code is really just the act of making a computer do a thing you want it to do, for some definition of "thing you want it to do". Architecture is more about understanding which things you want the computer to do, and in which ways.
There are a million ways to code a task. That's the "code" the original statement is talking about. Understanding which of those ways is an appropriate way is a separate skill, whether you call it architecture, or something else.
I am quite plainly talking about writing code that runs efficiently to support a wide-variety of tasks. To do that, one needs to write code that runs fast on your targeted platforms and is extensible/easy-to-modify (not necessarily the same thing to be clear).
We may have different definitions of "architecture" though, I tend to think of "architecture" at the system level, i.e. "this service handles these responsibilities, this other one handles these, they communicate with this interface/contract, etc". I can see how you could take the term "architecture" down to a lower level where you talk about classes/files passing information between each other too. I think to do that sort of lower-level architecture well though you basically need to write code in your design, even if it's just pseudocode.
> a sufficiently complex consumer or enterprise app winds up having big performance problems if people don't know what they're doing
Yes, and absolutely nobody will care if it does the thing it was meant to do. Performance is near always an afterthought because there is no single team that gets judged on performance.
I think we often don't realize how much performance is part of the user requirements (i.e., "the thing it was meant to do") because users don't specify that as a requirement. And when they do we get all engineer-y about it and start asking about TTFBs, throughput rates, TPS's and nobody gets anything sensible out of the conversation. But users don't mention it because they don't know how slow complex systems could be or how complex a mere CMS could be that for them this is one of those requirements that don't even need to be said.
Anecdata time...
There was once a scrappy start-up who, like all scrappy start-ups, was taking on the heavyweight incumbent gorilla of the industry. They started poaching the small customers from the gorilla, just enough for the gorilla to notice. These customers often cited how "fast and lightweight" the start-up's platform was compared to the gorilla.
The claim wasn't really supported by Grafana. The numbers weren't bad; in fact they were very average. For some metrics, the gorilla was actually still the gold standard the scrappy start-up targeted. The engineers suspected "fast and lightweight" had more to do with the user experience (they had smoothly-animated loading screens) than actual server performance. Still, it's not a complaint so they took that as a win.
After a couple of years of steady growth poaching from the gorilla, they started getting bug reports of slow performance. The customers have been seeing more and more of the smooth loading screen animations and less of the data they actually need to work on. And this time, the claims were supported by Grafana! There was no way to massage the statistics to even claim the reports are outliers or to pass the blame on to the unreliable ISPs.
The problem, it turns out, was that they were sending emails as notifications for a bunch of user actions and at that point there were about 2-3 such user actions per minute. While they could async some of those, there were a bunch whose succeeding states assumed that the notifications have been sent.
After three weeks of profiling and going through the whole performance optimization playbook, the fix boiled down to a one-liner in SQLAlchemy that offloaded loading notification mailing lists to Postgres cursors rather than loading whole lists into memory in one go.
Moral of the story: no one is asking you to build a racecar but that doesn't mean performance is not table stakes. A good senior engineer knows just where the balance is to still deliver business value. That is the salary you are paying for.
Yup. And performance problems don't just bleed the user base, they also slow down development and testing internally, both directly and by nudging developers away from attempting some tests or use cases in the first place.
I'm not american, and didn't follow that one deeply, but presumably that's not just "due to bad req. gathering", it's also due to the structure of gov procurement? E.g. it wasn't the pained users who approve the payment to the contractors, right?
You could counter "if only performance was legally included in the contracts, a better site would be delivered."
Maybe, but my point is there is big difference between internal "req. gathering" that informs work while everyone is long-term motivated for good user experience anyway, vs. external contract/deadline gathering for almost adversarial "deliver worst thing that passes and walk away" settings. Brushing both under same wording feels insufficient to me.
Web software I don't know but there are many "modern software" that were meant to replace COBOL code running on AS400 that ended up never making it to production because they were running so badly and projects ended up being money pits.
I can understand when people say the code was the way part, but under the assumption that the system design and architecture are clean, code is high quality or the project is greenfield, and there is proper testing and validation. Then, sure, the lines of code aren't the hardest but that's only because that hardest work was front loaded and given a different name. Even then it's still not always easy.
Getting to a state where those assumptions are true is HARD. And takes a lot of careful programming.
Yes. Once it is true, the code is easy to write. But only because a lot of effort went into making it easy. And keeping it easy is also hard. Without focused effort to keep the code clean and easy to modify, it starts to rot.
Wow that article made a hard right turn about halfway through.
"Most organizations improperly account for engineering teams and incorrectly consider both code and team growth to be assets when in fact they increase complexity..... but LLMs can fix all of this"
Wtf?
Measuring things that actually matter is a great way to improve clarity on a team, you can probably just stop reading this article at the halfway point.
EDIT:
Specifically this paragraph is insane
"The obvious objection is that code produced at that speed becomes unmanageable, a liability in itself. That is a reasonable concern, but it largely applies when agents produce code that humans then maintain. Agentic platforms are being iterated upon quickly, and for established patterns and non-business-critical code, which is the majority of what most engineering organizations actually maintain, detailed human familiarity with the codebase matters less than it once did. A messy codebase is still cheaper to send ten agents through than to staff a team around. And even if the agents need ten days to reason through an unfamiliar system, that is still faster and cheaper than most development teams operating today. The liability argument holds in a human-to-human or agent-to-human world. In an agent-to-agent world, it largely dissolves."
It seems like that has pretty substantial time lag. Maybe require the ai companies to build power plants before they're allowed to build data centers in a certain region?
If you have a site whose performance steadily gets worse and the rate of new features steadily declines and the rate of bugs steadily goes up, then your site/app will probably not have a great future.
All of those things depend on solid code. If staff engineers who are too busy talking and building consensus such that they aren't connected with the actual programming and situation on the ground, then all the talking and consensus-building won't matter.