Facts every web dev should know before they burn out and turn to painting
baldurbjarnason.com
baldurbjarnason.com
Switched to embedded systems 7 years ago to avoid the burnout. It is better, in my opinion. Funny enough, there is a natural barrier to entry that keeps most programmers away - You have to understand how computers work, how operating systems work and you have to be able to code in C/assembly. I have a lot of fun and actually picked up electronics as a hobby, which will help me better myself professionally. I think there is enough here to keep me entertained until I retire.
Though my stack has certainly evolved, it's been mostly the same since 2016, with really not that much new to learn. Adopting something released just this year doesn't seem like the most obvious choice when looking for a stable stack.
Old wine in a new bottle, basically.
I think for a lot of business cases they are going to replace js frameworks. They are domain specific (Rails, Phoenix, etc..), but they allow you to essentially replace a lot of SPA functionality with a library that takes an afternoon to grok for a back-end dev.
They won't replace React, Vue, etc... But they can replace it in places where a full js framework is overkill (which is probably a majority of the places that I see it).
As a backend dev, I think that they have incredible promise. They make interactivity MUCH easier.
I use them too, but even In this niche there are several, like liveview for Phoenix.
WordPress is stable and maintains backward compat for as long as possible.
It's a real joy to build things on top of as you know you won't need to run framework updates every month to prevent a Nasty suprise down the line.
I'm thinking of investing a little bit of money to buy myself my own equipment, since I want to use it for fun as well as for work.
That may or may not be a large amount of money for someone, but those tools can last you a good part of your career for the price of a low/mid range development laptop.
Dealing with anything in the GHz range is not only extremely expensive (order or magnitude more), but you also start to deal with far more complex problems that boil down to the need for a very good understanding of the underlying physics of signal transmission: concepts like impedance matching, crosstalk between signals on the PCBs, etc.
The design AND debug requirements are far more complex, and you need to account for a lot more explations of why something isn't working as expected ... and the software/firmware AND physical level.
For example, I learned about https://github.com/GlasgowEmbedded/glasgow recently, a bit of a niche kitchen sink that uses https://github.com/nmigen/nmigen/ to lower a domain-specific subset of Python 3 (https://nmigen.info/nmigen/latest/lang.html) into Verilog which then runs on the Glasgow board's iCE40HX8K. The project basically creates a workflow and hardware to use cheap FPGAs for rapid iteration. (The README makes the point that the synthesis is sufficiently fast that caching isn't needed.)
In certain extremely specific situations where circumstances align perfectly (caveat emptor), devices like this can sometimes present a temporary escape to the inevitable process of acquiring one's first second-hand high-end oscilloscope (fingers-crossed the expensive bits still have a few years left in them). To some extent they may also commoditize the exploration of very high-speed interfaces, which are rapidly becoming a commonplace principal of computers (eg, having 10Gbps everywhere when USB3.1 hits market saturation will be interesting) faster than test and analysis kit can keep up (eg to do proper hardware security analysis work). The Glasgow is perhaps not quite an answer to that entire statement, but maybe represents beginning steps in that sort of direction.
So, to reiterate - it's probably an unhelpfully broad question, and I'm still learning about the field so haven't quite got the preciseness I want yet, but I'm curious what gadgetry, techniques, etc would perhaps allow someone to "hack it" and dive into this stuff on a shoestring budget, on the assumption the ride would be a tad bumpier? :)
A logic analyser is cheaper than a scope, and does a much better job displaying this kind of data in volume. I'd say a DMM + some equivalent to a Saleae Logic are the two tools I couldn't live without ... IF you ever have to write drivers. But so much of embedded is about interacting with other devices, and it's a common enough requirement to have to port a driver over to a new chip, etc., that I can't imagine anyone regretting buying one sooner rather than later.
You can get by with printf, clearly ... but an analyzer is worth it's weight in gold for the right problem.
I'm not denying at all that a logic analyzer can be helpful. I'd just encourage people who can't justify the expense to have a try without one.
Edit: That said, I see that low-end logic analyzers are actually pretty cheap. I should probably get one!
So I may be in the market for a better analyzer soon. But all in all my $30 was a good investment, and has made it easier to setup new serial protocols.
However, looking at the data on a logic analyzer and being able to see several seconds of data at once showed that the external module I was trying to interface with was buggy. Turned out that the unit we had was a preproduction prototype!
Take a look at the reviews at https://lygte-info.dk/info/DMMReviews.html, they're very through.
If you’re thinking about making the switch, the hard part is learning all the things you didn’t know you needed to know. That’s where having someone you can walk up to, wait until they look interruptable, then ask a really dumb question is priceless, and really hard to replicate remotely.
That said, I do have a suite of hardware development tools since I've been doing this a long time. But the only times I've needed to turn on an oscilloscope recently was because I was doing some low-level hardware debug.
Once you get past the really low-level stuff like measuring signal levels or debugging a weird PWM behavior, i.e., the hardware is pretty stable and you're building out functionality, you really won't need anything more than a JTAG or SWD connection and the hardware for those is trivially cheap.
I'm actively involved with Zephyr RTOS, for example, which is backed by the Linux Foundation and has people working on it full time from almost all the major MCU manufacturers. The development tends to correlate closely to Linux kernel as a model, and a lot of the key members were/are Linux kernel contribs, so skills learning with Zephyr can help you move to Linux dev later if you're new to it.
There is a non-trivial learning curve with Zephyr (device tree, KConfig, etc.), but it has more momentum than any RTOS I've seen in my career, and it has a very helpful community, while keeping the technical bar high.
If you prove your worth there, it's also an avenue that can possible even lead to job opportunities, which I've seen and benefited from myself.
That may or may not be of use, but if you want to improve in the embedded space, getting involved with something like Zephyr is some of the best use of limited time in my opinion to learn from some of the better embedded engineers working in the open.
Same here. I managed to reverse engineer some of my laptop's USB functions and write Linux drivers for them. That little driver was the most fulfilling software development project I have ever made. Tried the ACPI and I2C stuff but couldn't figure it out. I really want to learn it all but I don't even know where to start...
You need a more fundamental understanding of how your MCU works (again, similar to any home PC in the 90s or early 00s), but once you learn those fundamentals they transfer very well, and knowledge has a high degree of transfer from one project and generation of devices to another.
I also find it highly satisfying to work on things you can actually touch or point to, versus spending 6-18 months of your life for something that just sits on a server somewhere as a cog in a short-lived system.
You do need a certain type of brain to enjoy this kind of low level development and HW design since there is some overlap and you often have to roll your own versions of common-seeming operations, and I suspect salaries are lower than in some shinier fields, but overall I've always appreciated the work I do, and the colleagues I've had in this field. The egos tend to be smaller, and the drama minimal since the people doing this kind of work tend to have been at it long enough to have some perspective on things.
Well, I personally quite near the beginning of my career had the exact same problem as the OP in the 90s. I started off learning the MacOSX API and C, then C++. Then started looking at Windows API - DirectX and COM were also new then (Win 95) and MFC was just getting started as a direct response to OWL and the Borland tools and VB 3.0 was starting to make big inroads into RAD dev. Then the straw that nearly broke my back was Delphi, which I have never used but was wildly popular and a 'must learn'. By the time Java came out I had decided to stick to the WIN32 API and COM and ignore the rest so I had a career focus but a lot happened in the 90's and it was easy to be totally befuddled as to where to focus your energies.
Programming is hard, let's go shopping.
I think you mean what's now called classic MacOS. System 7, Mac OS 8/9
>Programming is hard, let's go shopping.
What you are describing is not programing, but life and career choices, which is much, much harder in my opinion and most of us are sorely unprepared for.
>Programming is hard, let's go shopping. Phrase borrowed from Jeff Atwood :) https://blog.codinghorror.com/programming-is-hard-lets-go-sh...
>What you are describing is not programming, but life and career choices, which is much, >much harder in my opinion and most of us are sorely unprepared for.
This is true, you can either simply bob along on the currents of fate and take whatever comes to you, or try and take control. At first I was just happy with a job, and luckily (all my working life actually) there's been plenty of opportunities for my skills; but later chose more carefully. I'm sure that's the experience of plenty others too.
Assuming you mean more writing firmware, the biggest thing to understand is that embedded is all about C. You'll absolutely want to learn the basics of C and properly understand pointers. A key part of C is understanding data types (signed, unsigned, float) and notations you rarely used in other fields like hexadecimal which is omnipresent in embedded. If you grew up learning C#, node, etc., you likely don't properly appreciate these fundamental types, and you'll need to learn those fundamentals, but that will come with learning C.
For books, I like Jack Ganssle's "The Art of Designing Embedded Systems". He does a good job of laying a solid foundation for planning embedded projects. It's opinionated, but you could do worse than start with his ideas.
And start with a professionally maintained foundation for your projects. Arduino is good for some people, but it won't scale and won't give you the skills you need professionally, and scripting languages like MicroPython won't help you later in life. Use a language (C) and platform you can go to production with, such as Zephyr RTOS, Azure RTOS, FreeRTOS, etc. It's more work and harder up front, but the investment will pay dividends and you'll learn good habits from the start.
Not because it's great technically and not because the editor is great (frankly, it's awful). The reason I argue to start there is that they've made the first 15 minute experience stupidly easy and convenient and, as a result, it's become wildly common and popular and you can readily find Arduino-platformed examples for most of the basic electronics technologies. If you're the type to learn best when you can see glimmers of visible progress, Arduino gives you smooth on-ramp.
You will need to wean yourself from that reliance/training wheels at some point, but I think it makes the first 2 months 20x easier, especially if you're trying to learn datatypes, bit-packing, pointers, memory management, analog electronics, digital electronics, communications protocols, in-circuit programming, and everything else (PCB design?) all at once. Break it up a little.
As long as you eventually take the training wheels off, and know that Arduino isn't a path that leads to being able to create financially viable products, and it's a first step.
It won't teach you certain good habits, but it will perhaps get you hooked and motivated, which is useful in itself, and does give you the satisfaction of making motors whirr and LEDs blink quickly.
I agree that Arduino is not a good start if you intend to become a professional. Arduino works really well for the non-technical person who will never progress beyond the arduino ecosystem, and for the experienced embedded programmer who is well aware of its limitations. Beyond that, if your intent is to learn embedded systems professionally, pick up an ST Discovery development system (about $20 IIRC) and have at it. Although I worked for a company that standardized its embedded development on Nordic processors, I don't recommend them unless you need wireless in your project.
If you're looking for something to play with at the HW level, it can be overwhelming to know what to start with. Stick to Arm Cortex-M. That will get you the furthest the fastest IMHO. If I was to suggest one company -- even though they all have their strengths and weaknesses and niches, and I work regularly with several like NXP, ST, etc. -- I think Nordic Semiconductors does a very good job with their support forums, SDKs, tools, etc. BLE is also a very rewarding place to start since you can talk to your phone, laptop, etc., which is Nordic's niche.
A development board like the nRF5340 DK has a HW debugger on it out of the box (to program the MCU and debug programs), is reasonably priced, works cross platform, and packs a lot of processing and peripheral punch. Being based on the Cortex M33 it has a solid security foundation (TrustZone and TF-M), and works well with a first-class RTOS like Zephyr with open source networking and wireless stacks.
You'll find answers to common questions with this chip on their forums and online.
There are other options -- ST and NXP have many excellent MCUs and inexpensive dev boards -- but the nRF boards and the ecosystem around them make them a good choice to make a serious start and learning embedded, and they are one of the only vendors who reliably answer questions on their support forums. The nRF53 dev board brings a lot of value as a serious learning platform if you're getting started.
Again ... just an opinion!
There are fewer companies that do embedded systems, but there are also not that many developers. Headhunters call me a few times a month just to ask if I'm willing to change my job, since experienced real-time embedded systems engineers are so rare that they have to actually steal one from somewhere else.
Really, really, depends on your situation.
There aren't a lot of advertised jobs, but I think this is often because they tend to get filled via word-of-mouth and employability is rarely a problem for a decent embedded engineer.
It’s all just a process of convergence in my eyes. And if I put it in that way I can cope with it. Any new fancy library comes up - I check ok were have the ideas come from, language, environment etc. Go read that and understand the original concepts, and then watch the web dev slowly move in that direction.
To be honest it’s pace is sometimes actually frustratingly slow if anything. You can see some Ideas that have been tested and you think they would be great, but takes time to actually permeate into web dev.
I couldn't disagree more. Maybe it's my situation as a full-stack web developer that makes it different, but over the past 5 years my understanding of all the layers that a website interaction goes through (from mouse click to database and back) has only deepened, and none of it feels like it went out of date over that timespan.
Sure some company may use technology X for the job another company uses Y, but overall it feels more like different paint jobs for the same thing with slightly different trade-offs, than an ever-changing barrage of completely new things.
Nothing is static for any discipline.
Doctors have a constant influx of new medicines and procedures. The doctor that operated on my wife had heard of a just-in-case tip that ended up saving my wife from having full-blown have-to-get-kemo cancer. Most doctors still don't do it that way, and it's an incredibly rare situation... We got super lucky that that doctor was on the ball.
And while it's not life-threatening, I see the same kind of thing in webdev constantly. New 'best practices' come into effect all the time because of security vulnerabilities, and new tools come into existence to make hard things easier.
Yup, those same tools sometimes make easy things harder, but that's the trade-off. You do not need to make the switch. But it has its benefits.
That said web frontend has had a wild ride the past years. But its really starting to stabilize now, around a few core frameworks (react and angular for example). Sure there is still forks and revamps but its not the big world changing differences (like going from jQuery to react was).
Backend is much more stable, with the exception of Node, which seems to be suffering a disenchantment, a bit of reality check after the early euphoric years.
I am yet to be convinced that any of the 3 top frontend solutions (Angular, React, Vue) are worth the trouble.
There is also deno (https://deno.land/), from the same creator.
Embedded and system programming aren't much behind, because of Rust. Everything else isn't migrating to Haskelllike languages nearly as quickly, but most software will go eventually. The slowness is probably more due to bad market dynamics for the tools than to long term issues.
React is going on 9 years.
> even stablished ones keep changing in incompatible ways (Angular, React, Vue)
React's API has been incredibly stable. There has been one major breaking change in the API (deprecation of the lifecycle methods) and even those are still supported.
These arguments are tiring. Think of something new.
Even if class based components are still supported, the community is moving to hooks be the standard so you don't have much choice but to learn them.
Redux became popular and then has slowly been replaced by context and libraries like React Query.
- JSP, JSF and PrimeFaces in Java are essentially dead (server side and hybrid rendering technologies)
- Vaadin and GWT are essentially dead (Java to JS transpilation of sorts)
- AngularJS is essentially dead (Angular 2+ are way different)
- jQuery is on its way out
- class based React is on its way out
Each of those have a lot of internal complexity that i'd suggest is more than just a paint job. Of course, it's inevitable that technologies that didn't work out for one reason or another will be sunset and will die out, however at the same time there is definitely churn.For example, we don't know if something like Bulma or TailwindCSS will work out and will be around in their current form in 5 years. You could say the same about how state was managed in React, nowadays we have MobX and Redux, but also the Context API. You can say the same about most languages, approaches, frameworks and libraries - nothing is set in stone.
I'm not sure whether that's a bad thing or a good thing, i just personally hope that eventually the more stable approaches will survive and the developer experience will be all the better for it, as opposed to introducing more and more complexity to the point of rivaling that of JSF/PrimeFaces.
My personal approach is just vaguely along the lines of:
- learn the fundamentals that are unlikely to change much (abstract concepts, architecture etc.)
- learn the most common technologies, refresh knowledge every few years (HTML, CSS, JS)
- learn the frameworks and libraries to the point where you feel vaguely competent with them (React, Angular, Vue, have a vague idea of how to do stuff with CSS libraries/frameworks like Bootstrap)
- maybe pick up a few useful tricks here and there, if you have the time explore a new technology or two in non-prod projects every now and thenBut now, with hooks, you might instead have 3 or 4 useState hooks, each of which could cause a component update. Worse yet, with useEffect hooks, you might run into the interdependent dependency array problem, which would cause a refresh loop.
Now it feels like your components have now become containers for smaller loosely coupled units of code with their own behaviour and life cycles, all of which may result in lower coherency as well.
I actually voiced some of my concerns a while ago in a slightly satirical portion of my blog, called "Everything is Broken": https://blog.kronis.dev/everything%20is%20broken/modern-reac...
With hooks, it is easy to create re-usable state controllers than with class based components. Components that use hooks are easier to read, understand and modify. Hooks are also easier to test and annotate with typescript.
In classical class based component you would often have complicated code in componentDidUpdate, componentDidMount or getDerivedStateFromProps. Code ended being complex and interaction between lifecycle methods and constructor hard to debug.
Disagreed. It's likely that there are factors at play here that we're not considering, such as personal preference or certain people enjoying different patterns more.
> Components that use hooks are easier to read, understand and modify.
Hard disagree. In my experience, hooks take a single concern within a component (whether it should update, or reacting to a certain event within it) and scatter the logic throughout multiple hooks in any non-trivial application, which leads to the control flow becoming harder to understand and lower overall coherency of the code.
> In classical class based component you would often have complicated code in componentDidUpdate, componentDidMount or getDerivedStateFromProps.
This feels like an indicator that you should split your components into smaller parts and compose those, as opposed to look for other ways which may or may not be better (because of the aforementioned differing preferences) to express that same level of complexity.
> Code ended being complex and interaction between lifecycle methods and constructor hard to debug.
I apply this very same quality to hooks.
I find most frontend libs code too convoluted to be able to understand what is happening just by taking a glipse at the code.
In contrast I've doing backend in .NET since 2008. To catch up with the latest releases I need at most a couple of weekends a year and probably less.
This is definitely a valid concern, especially when the authors of some frameworks attempt to be "clever", which unnecessarily increases the cognitive load that one has to deal with.
That said, it's also probably a matter of the abstractions that are used, for example, in Java for back end you can use any of the following: Spring, Spring Boot, Dropwizard, Quarkus, Helidon, Vert.x, JSP/JSF with something like PrimeFaces, Apache Struts, Play and others. Whenever you run into a framework that uses MVC or its own way of templating, you're stuck learning all of its specifics and idiosyncrasies, even if the end result that you want to achieve is the same.
Thus, i'd posit that if you're not the person making the choice of which framework or library to use (the ones that you're familiar with), on some level you've already lost.
If you're used to Angular, for example, but instead get thrown into a project with React, Redux and Tailwind CSS because someone wanted it on their resume, you'll both be less productive and will look less productive compared to everyone else.
Paid to learn. Does that sound noble? Maybe it is. It depends what you're learning, frankly. Learning to code for the very first time, and seeing the fruit of your imagination materialize in front of you? Great! Learning the idiosyncrasies of a system that was designed to dodge responsibility?
Yeah, there is churn in JavaScript frameworks but to me that’s all they are: frameworks that sit on top of the DOM, and the nature of the DOM (for better or worse!) hasn’t changed all that much in a long time. When I think about what those frameworks are actually doing there’s a lot of consistency (this thinking also helps you avoid the stupid turf wars)
I personally like that’s there’s no “up” in web development. I’ve gone from perfecting REST APIs to understanding video encoding and streaming, to sending data via WebSocket or WebRTC… the list goes on. I hope someday soon I’ll have an excuse to dive into WebGL and WebAssembly.
And the development environment (i.e. the browser) is actually pretty wonderful compared to XCode, Android Studio and the like. There’s a reason native developers have pushed and strained to get things like hot reloading that browsers can do very easily!
-You need to be an expert* JavaScript developer with strong understanding of computer science at the same level as say a Java engineer.
-You need to be an expert on cross browser, cross-device and cross-OS compatibility and performance of Javascript, HMTL, CSS.
-You need to be an expert in animations, transitions, SVG, canvas.
-You need to be an expert of analytics, statistics and presenting data.
-You need to be an expert of responsive design, accounting for countless myriad possible platforms, compatibilities, viewports, constantly evolving standards and best practices.
-You need to be an expert of accessibility, semantic html.
-You need to be an expert in working with various types of databases, or API and local storage, caching etc
-You need to be an expert at test automation, writing unit and integration tests with increasingly high stakes.
-You also need to spend time and have strong understanding of ancillary issues, such as package management, devops, CI etc etc
-You need to do all this and your work is pretty much almost entirely customer facing (or stakeholder). People who don't understand the constraints, or dont appreciate the difficulties of what a problem may require.
And this is without talking about things like Typescript, React (and the millions of other dependencies, libraries, hot new things) you have to deal with
Just look at the URL shared on this article and see how many subject mentioned were totally not part of web dev say just 10 years ago.
5-10 years ago my job was:
- build websites with a bit of javascript DOM, ajax, or jquery UI interaction
Now my job is:
- same as above but with the added responsive aspects
- building single page applications
- building browser extensions
- building command line tools
- building react native mobile apps
- building electron apps for desktop
- writing tests
- building tooling and managing dependencies
- building internal libraries, style guides and associated documentations
*this is the expecations, i know the reality is not really the same.
I would put Java engineers in the "software engineering" category more than the "computer science", but that may be just an expression of my bias.
The good news is that none of the successful lead web developers I have worked with meet these requirements. I feel like you're talking about a large team more than a single developer, and in many places where you say "expert," I would say "willing and able to tackle the subject to the extent required."
I think a better way to sum up web development, instead of making it sound like an impossible job, is to say there is virtually unlimited scope to make yourself better and more valuable at the job by expanding your technical skills.
The "expert" expression is abused by approximately the whole tech sector. No one meets those job requirements anymore, and yet the world (of web development) still moves on.
If you did you would realize things haven’t changed that drastically in 5+ years now. The new libraries and frameworks are small iterations that take a weekend to check out and pick up.
Once you have the deep knowledge you’re set in this field. The problem most people have is that it can be less straightforward and much wider surface area, especially if you’re doing stuff like React then React Native, and also trying to understand native libraries while also bundling code for both platforms.
I think the issue is the fact that the browser has no native rich and efficient components like desktop tookits have.
So you implement some coold grid view to showcase all the user projects but later some user created many projects and because angular performance is garbage you need to solve it now, You can do a shit solution and implement pagination or waster your time and implement a DataGridView similar like in desktop toolkits that is actually smart and efficient or maybe you do the shittiest thing and install some random stuff that might give you what you need. Same problem would not exist on desktop and probably mobile tookits.
Repeat same issues for all possible widgets that exist in a mature toolkit.
On the web you always spend a lot of time on shittiest things instead of the cool part. A designer wants say a horizontal scrollbar that would work only with the mouse(no Ctrl to press) =? install a library, a designer wants a dropdown with some extra styling -> install a library (or create a inferior dropdown - see YT autocomplete one that gets stuck on all the time) , modals -> create your own system. The only widget that is not handicapped in the browser is the text input one.
People will say how in the past on desktop you can drag and drop widgets and make the app , the reason it works is because those widgets where powerful and efficient. Probably mobile devs can understand this point, you don't have to hunt for a framework or library to get a smart and efficient table widget.
If this is the case, then i congratulate you on being a pretty productive and capable front end developer!
However, that's definitely not the case for me and many other people: i'd say that you need at least a week to get comfortable with both using technologies, ways of misusing them, their footguns and to get a deeper understanding of what you're actually doing. I've seen sites fail to work correctly because people attempted to use React hooks with overlapping dependency arrays, where one of the hook bodies calls a state mutation, which ends up in an endless loop and breaks the entire page.
If hooks indeed were such a small feature that could be reasonably understood in a few days, then we wouldn't see cases like that, nor would it be difficult to write your own hooks. You can say the same about the Context API, as well as the migration from class based components to the functional ones.
If that's the only set of technologies, then good. But i work in a company that does consulting and occasionally i have to unravel messes in everything from React, to Angular, to Vue, even jQuery and AngularJS. If i want the lifestyle where i spend long evenings and weekends of my own time working on learning these technologies, then sure, but the company has neither the resources nor the patience to wait for days to weeks until i become productive in a project.
Is that a social issue rather than a technical one? Perhaps, but at the same time these kinds of factors cannot be ignored. Sure, the churn isn't too bad and hopefully has good outcomes in the end, but at the same time it definitely is there and sometimes it definitely is detrimental from the point of view of just getting things done (e.g. AngularJS needing to be abandoned for Angular or something else - it should be better in the end, but as someone who has a rewrite of an app that has had thousands of hours sunk into it looming over me, i'm not overjoyed).
Examples of this deep knowledge?
Maybe this is the root of the problem. Should you need that deep knowledge in order to be proficient? I mean, the point of so many libraries and frameworks was to remove the need for a deep understanding of the underlying technology.
Perhaps the need to understand it deeply indicates that they've largely failed?
React is going on 9 years people.
I have a friend who manages a dev team in a small webdev shop (~8 people total) and is about to quit because of the customers delivery schedules. These customers are BIG name (billion dollar) companies so they feel pressured to grind and get the site built otherwise the customer will just pay some other desperate company who will. So it seems that on top of tech churn there are insane customer demands ruining the mental health of everyone involved.
Then you are doing it wrong.
Focus on the fundamentals, not the implementation. Any job or degree that doesn't value growth and a good grasp of the fundamentals is a pretty big red flag.
> It’s for when you have that theory contained in a worldview in your mind that helps you quickly test out decisions and plans against that theory.
> Until then, you should repeat yourself. Seeing your code repeat itself – when rhyming phrases start to pop up throughout – is a vital tool for building a theory about your app.
Wow, this is the best explanation of how to apply DRY that I've ever heard.
I mean, while the explanation above is nice, it's fairly easy for a junior to speed read through it as "DRY is a luxury [...] You should repeat yourself [...]" -ignoring all the parts that sound too complicated or nuanced- and quickly jump to the completely opposite conclusion.
What’s more important IMO is to keep things together and in harmony. As in the same file, or similarly named files, or something that let’s you see it somehow. That’s a structured kind of repetition that is rarely harmful.
The problem with DRY is when you have multiple knobs at different places that you have to turn in sync that are structurally unrelated. Now you need to refactor or redesign to have a clearer pipeline and knowledge representation.
DRY problems can often be symptoms of bad structure. You can only accidentally fix it by patching or abstraction over repetition.
On the other hand, if someone finds that one instance of the duplicated code really is different, they either turn it into a new function (the right answer) or add a new argument. Even if they take the wrong path by adding a new argument, it's easier to turn that one function into two functions than merge 5 to 10 different versions of what should have been the same code.
Am I misreading this comment perhaps?
The comment and the article doesn't advocate repetition for repetition sake. It serves as a warning against prematurely trying to "factor out" seemingly related code that can, later or in that moment, prove to not be exactly the same. This complicates the "refactored" or "improved" piece of code, as it now has to serve different purposes, maybe requiring more parameters, or a more complex state input. This further complicates the callsites of all the clients of the new DRY piece, adding complexity to the system which is more often than not worse than the original state.
It also makes everything around those places more difficult to change over time.
Since this "refactor" is often easy to spot, it tends to be abused by less experienced developers trying to improve things, or "advocates" of this practice that aren't in touch with how it can end up causing more damage than it fixes.
A DRY refactor has much higher chance to stand the test of time if you know enough about the system and how it will evolve at the time of performing it.
As with most things, it's about striking a balance. Since the internet is full of DRY! refactor! advice, this serves as a counter to the mindless call to DRY by adding some nuance.
But OFC there are instances in which code that is exactly the same is copy pasted around even if it's known one won't diverge from the other and done out of laziness... that'd be the trivial, positive DRY refactor case.
1. you are writing some code, there are a number of functions dealing with similar things and you know how all the stuff relates to each other, you find yourself repeating some code in places and immediately realize you will need to repeat it a lot of places because all these things are related together. So you make a function you call.
2. You have come to a new codebase you don't have familiarity with, you see some bits of code repeated around in various places and you don't know if this is just because the things actually are related to each other or if it is basically by chance. You replace these bits of recurring code with a function. Later on people keep coming to your function and start adding in parameters and branching logic to handle the different use cases that keep popping up in your application where it is being used because there was actually not a very tight logical connection between these places it was being used and as a consequence over time the places it was being used are diverging in their needs.
Code should be kept alive. It is fine to DRY wrong. You can make it better when you discover a better way.
Premature abstraction is premature at the time of abstraction. It aims to address future needs that may never happen. Wrong DRY is correct at the time of abstraction. It is wrong only in hindsight when a different need that is not addressed by the DRY arises in future. In that case, it should be easier to change the abstraction than to find duplications and DRY them. DRYing early also allows getting the benefits early until the needs change.
-Spend most of my time dealing with tooling issues.
-Increasingly complex demands. Even the simplest problems now seems to be multi layered with dozens of edge cases to be accounted for. It's seemingly impossible to get anything right. You can spend hours testing a responsive design on every browser, every viewport - send it to the client and you'll get after 5 minutes a list of 50 issues, half of them totally asinine.
-Lack of respect/authority/autonomy. After 15 years I'm considered a subordinate to a PM with 6 months experience and zero technical knowledge. This one can be improved a little by working remotely I think. But it just comes down to how management view or value different roles. We are a liability to them, something to be managed, coerced and controlled.
-Oversaturated market, learntocode, let's be honest and say for 95% of companies, web devs are a commodity. I don't have an issue with people who are excited and want to learn coding, but the reality is the job market is over stuffed.
-Leetcode interviews. I just don't have the energy, desire and sometimes specific knowledge to deal with these interviews. Its a straight no from me now, if i get contacted by a recruiter requesting I do one of these.
I can see clearly that other people in non technical fields are getting paid better or the same as me and dealing with far far less work and far less stress.
It's like there are two type of work category: "reviewers" and "implementers". Reviewers are the stakeholders, they make all the demands and do none (or very little/superficial) of the actual work. Implementers, well we are the ones who do the heavy lifting and deal with all the real problems.
I just spent 3 days debugging a bizarre frontend issue. Turns out I just didn't understand how webpack works and was loading it wrong.
And once I fixed that, I had to fix my postcss config because something somewhere had a breaking change at some point.
I feel like almost everything I learn these days is how to deal with the idiosyncrasies of dozens of versions of dozens of tools. My actual programming ability is stagnant. That's what's burning me out.
Just a small taste of my day, another rabbit hole to get lost in for a few hours whilst deadlines for actual work are looming.
It's interesting you say that.
Based on one source [1] there is a 10% decrease in job outlook 2020-2030 for "computer programmers".
Another says [2] there is a 22% increase in job outlook 2020-2030 for "Software Developers, Quality Assurance Analysts, and Testers"
"Info Security Analyst" [3] shows a 33% increase in job outlook 2020-2030
Yet in another another... The annual projected job openings for software developer for 2018 - 2028 is 134,000. [4]
That's 1.34 million job openings over the course of those ten years.
[1] https://www.bls.gov/ooh/computer-and-information-technology/...
[2]https://www.bls.gov/ooh/computer-and-information-technology/...
[3] https://www.bls.gov/ooh/computer-and-information-technology/...
[4] Visualize it: Wages and projected openings by occupation Domingo Angeles and Elka Torpey | November 2019 -- https://www.bls.gov/careeroutlook/2019/article/wages-and-ope...
The reason is simple.
The average programmer is a newbie with little to no experience.
It's like a pyramid or a triangle. There's more area or volume at the bottom than at the top.
Every year, more new people arrive at the scene.
New programmers are easily fooled by "shiny" objects.
So, whatever place you join, there's a high likely hood that the culture at the place is dominated by what is considered popular, with little to no regard to what actually works well.
It's different at each place, but almost every company I've been too has things setup in a way that's very painful and frustrating to work with. Every thing takes many steps. "Compiling" javascript takes 3 minutes. "Hot Module Reloading" takes 30 seconds and refreshes the page 5 times. You have to jump between 4 different repositories to fix a small bug. etc etc etc.
If you are experienced and notice that things at your company are broken, you either try to advocate for fixing things or just leave out of desparation. So the organizational culture continues to be dominated by people with very little experience.
If you are not experienced, you may just think that the "suck" you have to deal with on a day to day basis is just what progamming is like, and you might well decide to quit programming. It's hard not to think so when you have never seen a better version of how things can work.
Just know though, that there are different places out there. I surely am tempting Murphy right now. Please recognize my sacrifice.
My current place is rather good in this regard. People actually care. The Devs genuinely care about both their work environment and code base. We actively try to hire other people that care and not let in the ones that don't.
We do hire 'inexperienced' as well but that doesn't mean you gotta take bad dev experience. For example I have a really 'inexperienced' guy on my team. But we hire him anyway because he showed signs of 'caring' during the interview and coding challenge (take home - I know what you think. It's different than you think and I'd be happy to elaborate if you want to). He is awesome! I try as hard as I can to give him the space to be awesome and not let the 'bad parts' of the company (which exist even in awesome companies) reach and discourage him (and others like him).
We keep our builds fast, we spend a bunch of money on giving every dev a prod like environment. A monorepo.
Now I am/have been on both sides of this.
I happen to like take home for devs. I like it because it takes out some of the stress of interviewing. If done right. I have been advocating internally at my company for stripping down the take home test. Who wants to do a "this should take you 4-8 hours" test? Which nobody internally actually tried to do themselves in that timeframe. Nobody! Especially not if you have a job at the moment. And a family. But want to take advantage of the market and/or look for a better company.
What do I look for in a take home?
Not running code! I couldn't care less! I have never in my life run up a take home test someone sent in (backend). I look for code cleanliness, consistency, abstractions, DRY, WHY comments. If you send in something without any tests you are out. If you have a hundred tests to show 'you do tests', you are out. If you have 5 tests that are of awesome quality and show that you know what is worth testing and how to write tests that will survive a refactoring of the code and actually tell you that your refactoring didn't break anything I will hire you and pay you money to write a hundred of those tests when it actually matters. Maybe add a comment that you could write the same kind of tests for the rest of the code but your kid needed a good night song and the deadline for the test was up.
I was hired on such a take home. My code deliberately did not run. I called out to external services that I did not bother to include in the take home test because it asked to solve the problem and I knew they used microservices. And business wise those things should've been handled in those other microservices and not the one I was writing. I also left out the database. Not worth even an h2 in pom.xml. They happened to use gradle. They didn't care I used maven. Still love them for it. Had the best interview ever. Loved the pros and cons discussion with my interviewer. Awesome guy.
Now depending on what position you get hired for this might change. An architect position for example a whiteboarding session might be more appropriate. Just have a problem to solve (e.g. one of your own main use cases) and have them design it with you. Who cares if they come up with the same solution you did. It's about the discussion. The pros and cons. The general attitude towards solving the problem. If they admit they don't have the answer to something off hand but its a 'googleable thing' they've just never had to solve before, that's fine!
1) we want the time investment to be <4 hours
2) the test uses public APIs and is directly related to our work (crypto)
3) we had the team (mine) do the test themselves before making it official
4) we also are looking for things like tests, thoughtful architecture, etc. It's hard for a junior dev to fake well structured and organized code because it takes experience and thought to do it that way.
If I were interviewing I would much prefer a take home rather than an in person leetcode interview. I also don't mind in person pair programming (like help us fix the bug in this code or whatever).
It's tricky, because this can vary within one person across time. For example, in my area (DS), i think that the take-home gives the best signal for the actual work (as long as its well scoped).
But, as a parent of a small child, I'd much prefer to just do in-person tests/discussions as it takes less time away from my family.
So it's hard, and whatever you choose will lead to you missing good candidates.
Unfortunately, as in many areas, there's no silver bullet.
You have to understand, many of us think microservices is a stupid idea, so the fact that the core of your argument is "monorepos make microservices difficult" is not an appealing argument.
If a monorepo puts a barrier in the way of turning everything into a microservice, then all the better, as far as I'm concerned.
You trade simplicity of having everything in one place vs. ability to independently version pieces at the cost of more complex tooling and build systems required to test.
Usually there's some sweet spot, but the answer isn't obvious and one isn't clearly better.
Container based solutions become harder? Again… build your artifacts and deploy all the containers you want? What is so hard about this?
Meanwhile, with multi-repo you lose out on a whole host of opportunities to robustly track dependencies and keep things up to date.
Everything in software is about dependencies, and monorepos are playing double or nothing with dependencies.
The issue with Monorepos is that they can amplify bad decisions and tech debt. Any bad decisions are magnified across the organization. But they definitely don't make it easier or harder to make that initial bad decision.
The upside is that dependencies are just there and not hidden behind interfaces.
The downside is that a bad dependency cannot be abstracted behind a micro-service interface. Once it's out in the wild it can do crazy things.
not liking microservices myself but - if I did this wouldn't it mean that the code in version 19 was now removed from the code in version 18 and back in git history making it more difficult to figure out just where things went wrong on a difficult little edge case.
git bisect helps to easily identify hard to find but reproducible bugs. Since we try to have small PRs once you found the breaking commit it is usually easy enough to the find the bug. Murphy and exceptions obviously apply.
We do not version our services in that sense. It's a monorepo after all.
We do have microservices.
We use kubernetes.
Deployment is a breeze. Only services with changes are actually deployed.
We do hourly deploys to production.
None of the issues you describe apply here and the monorepo works awesomely for us. This is a SaaS situation where all services making up that SaaS solution and that we host are in that monorepo.
YMMV if you are in a different situation such as having to ship versioned software for customers to self host/install for example. Our accompanying software that is usable in conjunction with the SaaS solution is not part of that Monorepo and each of those are versioned and deployed to various external marketplaces.
That is way different from providing v1 of your API and changes come out in v2 of the API while you also still provide v1 of the same API. You can (and we do) do that perfectly well with or without a monorepo. Mostly for the public API. Internal API's often don't need to do versioning and one can go with backwards compatible changes and/or rolling a change out over multiple commit deploy cycles.
Some of this will depend on your size I suppose. The larger the org, the more services etc. the more stable versioning I would suppose happening.
Which is why I said in my original comment this may work fine in a small environment, but it won’t scale well.
That said, we're not small either. In our niche, which you might recognize if I said more, we're the top solution customers choose (but I won't go into much more detail than that for obvious reasons).
Saying that "monorepos are only good for large scale" is pure bullshit, and something that only someone very inexperienced would say.
I'm in a very small company (less than 10 devs) but we still use a monorepo, because we have a set of common libraries for all our products, and having a monorepo helps us update those libraries without breaking anything. On the other hand, some very large companies have tried and have failed.
Monorepos are just a tool. The implementation and the context matters more than anything else.
Monorepo forces the tough conversations. Maybe the organization should only use 1 language now. Maybe we should talk about code review policies and standardization of other processes since everyone is in the same bucket. Why can't everything just compile to 1 exe?
Another massive advantage with a monorepo if you use GitHub is that you now have 1 issue bucket that covers the entire enterprise. Linking issues to commits is super powerful when this technique covers 100% of your code and exists under 1 labeling scope.
Speed is a big deal for us too. The entire thing can be built from clean in ~3 minutes by GH action workers. We buy our developers threadripper workstations, so local rebuild times of the solution during typical development iterations are closer to 15 seconds. We are much more interested in developer ergonomics than with simulating prod environment.
I genuinely believe having fast builds is the most important part of the developer experience. Somewhere around a build taking more than 30 seconds is when bad things start to happen to my engagement loop. If I can keep it under 30, I can stay in flow the whole time. Other developers on the team have expressed similar tolerances.
I care mostly about cached build time. A clean build time of eg. 1h does not bother me.
This, a thousand times. Anything after 30 seconds is where you start to lose your focus, and your work output suffers for it.
here's an example in haskell: https://www.willamette.edu/~fruehr/haskell/evolution.html
For me this one also seems inevitably connected to the idea of microservices, where people set them up in the worst possible way (de facto tightly coupled interfaces but with REST or RPC calls in the way, separate git repos, multiple databases and multiple Docker/Kubernetes deployments for even small projects, etc etc) and so add huge amounts of developer overhead to web apps that would have been single Rails projects back in the day.
Maybe instead you could probe at interview time whether they are happy with their microservices, how many do they have, do they feel happy that the service boundaries they finished up with are the best possible etc.
Not all microservice setups are shit shows.
Plenty of monoliths are.
I've found it incredibly hard or impossible to gauge the quality of a codebase during interviews. (Beyond immediate red flags like "oh, we don't write any tests or do code reviews" or whatever.) And to be honest, most codebases are bad, it's just a matter of degree. And I would almost always prefer working in a bad monolith than bad microservices.
Yeah they are. One service per team, the thing that Amazon was originally doing that was the inspiration for all this, works, but you wouldn't call that "microservices" these days; the thing that people call "microservices" is always a shit show.
I needed a place to store marketing and PR templates that were completely unrelated to the core of our product.
Of course the rule was "one service per team", so the CTO demanded that I store it together with our service, which is the part that performs customer authentication. Meaning, the part that is responsible for securing customer data and everything else. Whenever we had auditors checking it they're puzzled as to why there's marketing material storage inside the auth microservice.
This could have been the poster-child example of a good place do have a separate service, but no, the law was the law.
It's almost as if there's no such thing as a silver bullet.
There is no way anyone tells you in interview that the codebase is crappy or that they are unhappy with.
You’ll always be told « well, like everywhere, we have legacy, but we learnt for it and now every new project is in [put REST + shiny front tech here] and we are happy with it. We migrate step by step ».
And then you’ll realize that the codebase they called legacy is what makes the company’s money, it’s not that bad compared to new project and is a pain to maintain because nobody works on it anymore except for urgent bug solving.
So, they’ll probably tell you that « they are happy with their microservices » (or quite happy) because they already try to fool themselves about it.
Oh yeah. But I've seen this also happening in frontend libraries, and sometimes even inside monoliths.
I find that inexperienced developers tend to break up services/libraries/classes purely because they believe that "code should be neatly organized", not because there is a logical boundary between two parts of a system. Thus, we get lots of tight coupling, chatty microservices, and 20 lines of imports at the top of the file.
I find that A Philosophy of Software Design by John Ousterhout [1] has a good rule of thumb: classes (and services, libraries, repos, applications) should be "deep, not shallow". The "surface" (aka the part that touches external components) should be as small as possible, while the internals should be larger. Of course that doesn't sit well with people looking to "neatly organise code".
[1] https://www.goodreads.com/book/show/39996759-a-philosophy-of...
Splitting code as a way to visually organize code can lead to tight coupling, which tends to be worse than large classes.
If you split a class but there’s still multiple “points of contact” between both, it wasn’t a good split at all.
That sounds unwise. I only ever split because the class is getting too large, or because some functionality is better off being moved to its own class. And those other classes also should preferably only have one or two methods exposed to the outside, there's nothing worse than a large surface area unless it's a library class.
> there's nothing worse than a large surface area unless it's a library class
Yep, exactly. Even big classes are better than tightly-coupled classes with large surface area.
The post seems to be a "listicle" of opinions, not facts.
If we embrace the opportunity to generalise like the OP, we might wonder if "every web dev" has difficulty appreciating the difference between fact and opinion
As for this top comment, is the use of the term "average programmer" significant, considering the OP is specifically referring to "every web dev". The parent comment appears to reframe the context from "every web dev" to "the average programmer".
I've tried the advocation thing several times, but it usually ends up being you volunteering to do a lot of extra work. And then working extremely hard to try to gather some sort of consensus or buy in from the team, and receiving either push back or non response at every step.
I've now decided to just try not to care as much. I focus on writing my tasks to the best of my ability and improving whatever small bits of code that I can along the way, but I now just consider the codebase the property of the CTO and engineering management. If they want me to focus on helping fix what's broken, then they need to assign me to it and allocate time for it.
That kind of sucks too and takes some of the joy out of work, but at least I'm less likely to overwork myself again.
Getting pre-approval consensus is not really the way to go about those things, at least not in that kind of environment. Anything "important but not urgent" will not get the sufficient level of consensus. Generally if you're faced with a problem where you're certain people will find it worth the effort after it's done, but where you can't get approval beforehand, going skunk is the only way.
Most of my steps forward in technical reputation have been from those efforts.
And then maybe the biggest problem is the whole "putting in extra voluntary work" thing. Higher risk of burnout because you're spinning too many side project plates. Either your main work gets impacted, you start putting in overtime, or management starts thinking they're not giving you enough work, if you have all this time to do side stuff.
This might surprise you but people don't like you fixing their mess behind their back. They take it as personal insult. They correctly recognize that you think what they did is messy and bad and you fixing it looks to them like an attempt to dethrone them from whatever little position they have carved for themselves within the organization.
This comment echoes that sentiment a bit, I think; there's an implicit dependency in there on the project not having a collective structural investment, whether that's explicit (overt, with explicitly delineated boundaries) or implicit (implied, fuzzy, part of collective culture), on the thing being fixed.
Of course, sometimes you actually can rewrite it in a weekend.
when they fail, they do not unfortunaly learn humility and do not end up back at the start (jobs on the line).
but instead massively descope the project and add a layer of 'shineyness' to the old working system. and now the company has to keep some of the old system in place, thus creating a service with two systems with two different type of technology. (pita for BAU run teams)
rinse and repeat every 5-10 years and the service now becomes a monsterous complex system
For a lot of people, toying with complex systems and configuration files is fun in the same way that puzzle games are fun.
These people don't play puzzle games. They already spend all their day playing this puzzle game.
They are not in the business of making something useful. They're in the business of pretending to be wizards who can weild technology to their will.
If they were in the business of building useful products, they would try to simplify the process as much as they can.
But since they're in the business of playing the configuration puzzle game, they have every incentive to not simplify anything.
The more complex it is, the more rewarding it is for them when it finally "works".
We had a new lead join, whose first job was as a Lead(!) and he insisted on adding a pre-commit prettification hook. Now due to the specifics of our work this formatting creates all kinds of bugs and means the local code you work on doesnt match the work on the repo or server, which is terrible but I have no power to change things because they've been taught to believe that this is the only way.
In addition, I think for most use cases having formatting-dependent code is kind of bad practice (not talking about indentation based code scoping à la python here). Although I do have the occasional struggle with ascii diagrams / comment formatting.
All-in-all I understand both sides, with a slight preference for using one. Manually formatted code in some cases can be much more beautiful than autoformatted counterparts. It's certainly not something I would impose; rather a team-decision after a short discussion.
Thus, the patch shown in `git commit --verbose` would be very misleading. It would show the original patch, not what was actually going to be committed. Due to the hook, any other changes that happened to be in the same file would be silently commited (even if they were never staged for commit).
Worst case scenario you can format code on your local machine using your preferred formatting rules. I prefer to do this with the A and B documents since they will be using the exact same formatting (B comes from a different repo/team without our pre commit prettification).
That points us to the source of all the complexity we have now: it’s not newbies who broke things, it was tooling written by complete idiots.
If you have a guy who always does a diff spam, just talk to him and ask him to separate his commits and minimze the diff spam. You don't need to ruin everyone's experience just to counter that.
An unfortunate observation: the majority of these projects were bloated, frontend javascript applications. In complicated backend applications I seem to encounter a higher SNR, and thus no necessity for commit-hooks.
Being able to "review" changes as clean set of patches is not essential.
The mindset of "we must review every change before it goes in" is not based in reality anyway.
Have you ever seen a system of code reviews produce useful benefits that would not be there without it?
You can always review already-committed code and discuss it within the team. It does not need to happen at commit time.
At my work we have this the "right" way in C# with a gerrit flow: run "dotnet-format --check" in the pre-push hook. So you can locally commit what you want, it must be checked before pushing, and it doesn't automatically change anything without asking you or letting you review it.
> due to the specifics of our work this formatting creates all kinds of bugs and means the local code you work on doesn't match the work on the repo or server, which is terrible but I have no power to change things because they've been taught to believe that this is the only way.
.. but this is the real problem.
I know I might get some hate for this, but one of the most demoralising things for me recently was to feel out that I wasted my life and youth for nothing. I spent 4 years in a CS focused high school, where 60% of our classes were just maths and CS, then spent another 5 years at the university. Even though most of the stuff learned there is theoretical and most of my knowledge comes also from freelancing and learning on my own, the actual formal education I think it also helped, especially in the university where we had some amazing professors.
What I see now is that everyone is getting into learn to code programs, a colleague from my company, who was a PM went to a 3 month JS/learn to code course and is now officially a "programming instructor", another friend was a journalist, took a 6 month JS course online and is now a "senior" developer. I understand and know people that switched careers, spent a lot of time on learning to code and are great developers, but most of the people aren't like that, and it feels somehow demeaning to our craft, that now after a 3 month online course, everyone is a developer.
I switched careers, spent a lot of time on learning to code and am a great developer but have to work alongside people who have a CS degree but consistently write poorly-designed spaghetti code.
Boot camp graduates probably do drag down the average competence level a bit, but it was already shockingly low.
In the same time, I think now people just take this profession for granted. I don't like being X, I heard that being a developer pays well, so I will become one in 3 to 6 months. I wouldn't be able to be a tax consultant in one of the big 4 for example, just by reading about taxes on Udemy.
First, dont consider your job is mainly coding, it's not, it's mainly solving problems. If your amateur journalist solve company problems as well as you with that little education: change company to solve harder problems, it's not their fault they re super good where they are and you're just the same seething you over educated yourself while stuck at changing button colors.
Now focus on how you solve problems beyond coding: do you understand requirements, can you even propose some, is what you build always either well working or fast delivered (both are ok, rarely done by the same people, both can increase your reputation).
I work in a large bank full of very old devs and empty of fad. I m a bit of a wild card because I m only 35 yo, so I know javascript for instance, prefer maven to ant, etc: but my true value is that I deliver prototypes fast that I increase in quality as they are used rather than spend 2 months hesitating over impossible edge cases: this worked fairly well and I have enemies as well as support, and that's fine. Do what you can, help your company, change if you're useless, and that ll make you worthy of the craft :)
This is exactly how I feel. Even having gone through a more practical IT education, most of the folks in my class were really really bad (and not very excited about programming besides). That combined with folks that do a little bootcamp and then end up doing some sort of frontend development is honestly just depressing. It's hard enough to help managers understand good vs bad engineering, I don't want to do it every day for the people I work with too. Especially not knowing that a large percentage of them will never get any better.
One of them is "I spent years to learn this and now these plebs can just learn it in 3 months then take my title?". I'm not saying this is _your_ emotion, but I certainly notice this in me.
Anyway, I think this kind of emotion is not productive. If programming really is so easy to learn then maybe we made a big mistake by taking a 4 year university program to learn it.
That said, I actually think programming is hard and whatever you learn in a 3 month bootcamp will in no way give you all the tools and experience you need.
The problem though is the average.
New programmers look out to what everyone else is doing in order to learn.
But because most programmers are beginners, it ends up just being a cycle of beginners teaching each other.
When people with experience do speak out, what they say sounds so completely different from what the rest are saying, so the beginners don't listen to their advice. They will think these people with contrarian perspectives are just weird.
Every company needs a website and there are plenty of cheap services offering to build one. But the real money is made if you can make someone's internal processes or production planning more efficient. For example, what's the worth of an AI that automates a process that currently costs $1 mio annually? Management will be ecstatic to pay you $200k annually to get those cost savings...
And for those tasks, you need a strong algorithmic and mathematical background.
Why do you say this? If you implement it via AI then sure, but I’ve done plenty of process automation without needing a strong mathematical background.
What I have in mind is speaking to business people to understand what they do, learn what the business rules are and write systems that implement those flows (and hopefully skip steps that are actually redundant).
Perhaps you meant something else?
But alas, I've spent 6-7 years learning and grinding, I wanted to be a proper web developer. Just this morning I read another post discussion about RISC-V and ARM architectures and thought to myself - I'm still an idiot. I have no idea what these guys are talking about. I still feel like an impostor. I've helped my company deliver some awesome products and get paid really well but theres is still too much I don't know.
Now Im in charge of training new devs, freshly minted CS grads and they can barely write readable code. I'm still jealous that they have a CS degree which can open many more doors.
See also the Dead Sea effect:
http://brucefwebster.com/2008/04/11/the-wetware-crisis-the-d...
If you’re “experienced” then you just fix these issues (especially the ones you mentioned)
One of the counter intuitive functions of code reviews is to keep the code quality just around average.
If someone experienced tries to fix things, his fix will look bad to the inexperienced because it's different from what they already know, so they will push back very strongly.
Unless you have an iron will, an iron fist, and an official title within the organization, it's near impossible to fix things.
- js itself which was worse and now is, ahem, less worse. npm kinda fits this bill as well
- solid libs and technologies made by people who know what they're doing (React, Angular, TS, etc). Of course, those are not perfect, but you can see the engineering behind.
- a mishmash of "works for me" crap done by people who feel like importing left-pad
Typescript is really cool, but no one on that team cares about "compile times". Of course what I actually mean is "type checking time".
There are very few good things on npm.
React has the right idea (The DOM is slow, so let's put a "virtual dom" infront of it so we minimze our interaction with the DOM), but the implementation could be a lot simpler (and smaller). See "preact" for example. But I'd go further and question the whole "Class components" and "function components" and "hooks". Why not just functions that take arbitrary arguments and return a vdom tree? You can easily add constructs for caching return values if none of the inputs changed since the previous run (some system like the 'observables' from Knockout or 'atoms' from Jotai/Recoil).
esbuild is really great, it completely changed my development experience. The interesting thing is it's not written in Javascript at all. It's written in Go.
Because most people are average, thanks to our Gaussian nature for talent. Besides, for most people, IT is a job, not a passion. Like in any industry.
It's true for everything, doctors, electricians, geographers.
So if you love your field, and you are passionate about what you do, enjoy that, but don't expect others to follow.
Still, I'd take DevOps problems any day over pure programming.
My devops consists of uploading files via scp and launching an executable via ssh.
"modern" devops involves a confusing web of config files and programs whose names I don't even want to remember.
I'd go further and argue that probably a lot of what makes "modern" web development terrible is kind of downstream from "modern" devops.
You can have the best and cleanest JS that targets FF, and have it fall over one million ways in other browsers (I'm looking at you, Safari). There is a level of respect that is lost, so far as the expertise of understanding the lowest common denominator across browsers, and actually getting that denominator to do something useful.
Front-end is, at the end of the day, much harder than backend. I understand why us backend people get praise: algorithms, distributed systems, coherency, performance, yada yada yada. Imagine coding against a system that doesn't behave consistently. No thanks.
Chrome is the new IE:
- introduces its own standards: check
- technologically superior in narrow fields: check
- forced upon everyone by the most powerful computer company at its time true a multitude of shady deals, bundling etc: check
- lazy programmers doesn't verify in other browsers: check
- will be abandoned as soon as they have crushed competition: jury is still out, bit based on previous behavior by defender it is more a question of when rather than if.
The same absolutely cannot be said for Safari.
Then you must read closer.
Even one of your cherry picked examples is plain wrong.
On the other hand, I would like to do some fronted if that means handwritten JS + some JS libraries and NO framework.
However, because frontend devs know that, they have build tools to support them. It started with jquery as an cross browser abstraction and has grown to a whole eco system ranging from websites like caniuse.com to editor plugins that check for features based on the current browser shares and your specific selection (e.g. browserlist) up to test-farm services like browserling.
I think what makes frontend development harder, is that standards carry a lot of legacy (you can't just redesign CORS and 3rd party cookies) and that you have a very diverse set of runtime environments with very different capabilities.
TIL! That sounds awesome. What are these called? :D
[1] https://github.com/browserslist/browserslist [2] https://github.com/amilajack/eslint-plugin-compat
For one I didn't mention "behavior among different web browsers". I think that's a red-herring in this discussion. What is hard about UI front-ends is not that, nor is it unique to it. It is the fact that you are providing something that's consumed by humans directly. Most of the heuristics surrounding that are fuzzy at best. It is an open system on top of that, because humans are wildly different in their perception of and ability to interact with computers.
I also didn't say "testing distributed systems is easier" than that. It's a completely different game. Contrast the language/jargon/papers/practices surrounding the two:
- Fault tolerance, CAP, ACID, replication etc.
- accessibility, affordances, interaction, perceived performance etc.
Which one of those you think lends itself more to test automation and engineering principles?
Whether you find one or the other easier might depend much more on how well you do and want to understand this difference and how well you apply that knowledge.
Most projects backend seems to be more complex but backend also get more slack. For example if there is a DB performance problem there is usually a DB-team to help with tuning.
Front end ppl are usually more on their own, since its expected they will have easier problems. That's not always true though. Some orgs are adapting and adding css specialist and design roles to enable more technical front end devs to focus on that.
I am currently reading that book [1]. Such a great book of ideas. Getting vendors to agree is a hard task, though. Some of that accidental complexity may be arising due to the essential complexity of vendor interaction.
Backend is pretty much just the complexity of distributed state management, plus whatever complexity you bring to it. If you don't need horizontal scaling at all, a ton of complexity just sloughs off.
Conversely, you can have the best and cleanest JS that targets Safari, and have it fall over one million ways in other browsers (I'm looking at you, Firefox).
To be clear, I work on SDKs, CLIs, and mostly server infrastructure components (daemons, schedulers, etc). I know problems within my domain well, and as a result I can model for them well. Take me out of that, and I have exponential diminishing returns. On top of that, I'm not a college grad. I'm self taught. I didn't see these problems near as much as college grads do, so solving them in 30 minutes or an hour is like filing my teeth down without a numbing agent.
Anyway, I am getting out of this industry and taking the money I've made to go into EE. Maybe these notes will help make someone make their interviewing or promotion process better though.
Electrical engineering? Getting a degree?
On other side, many college grads practice a lot for this specific type of problems, even if they don't understand fundamentals.
Then there are the companies that say they don't give an algorithm test, but actually do. They just sufficiently abstract the real question behind something that is semi-related to what they do, while ignoring that the way they solve it will never be congruent to my answer because their question is sufficiently scoped to be used with DS/A.
Any study that can confirm that?
I’ll be doing the same, except not EE and for different reasons. I really don’t want anything to do with this industry as it doesn’t even faintly resemble the reasons I started hacking around with stuff. The sooner I’m out the better, it’s clear I don’t belong.
Web devs are expected to acknowledge and obey the opinions of those with "pull", i.e. "Gary from sales", the CEO's wife, or whatever "hot new hire's behind" the company is currently blowing steam up.
Projects would always end up as "designed by committee" and way worse than they'd have to. Management just shrugs, even if they understand the problem. After 1-2 years nobody remembers why the result is as bad as it is and assumes that the web dev just isn't that capable.
But the web dev, even if he's got a "Head of.." title is never seen as equal to the Head of Sales or Head of HR, so the cycle continues.
I've heard many devs envy people like me who work in non-IT or non-Software companies: "Nobody understands your job so you must be able to do whatever you want!" - but the opposite is true, because people don't understand how little they understand about web dev. They think it's all the same, from building a service like Gmail to the CEO's teenage son's band homepage.
Around 2006 I've even got someone from marketing with no technical background whatsoever set up a "think tank" inside the company because his idea was to "create a Facebook competitor". As in, world wide social media juggernaut, using the resources found in our company: 1 web dev, 1 infrastructure guy, and one Windows help desk person. The shocking thing was that his superior didn't immediately shut him down, but let him waste everybody's time for weeks.
This is...something.
I'd assume painting is stable and bs free.
Struggling to achieve results can still hurt though.
Programming, which purely follows logic, is much less frustrating for people for whom logic is their primary mode of functioning.
It hurts but it's my own pain. I decide how much, the kind, the time...
In it jobs, social interactions cause so much friction, information uncertainty, bad dependencies .. it adds to the raw effort.
That said it also helps avoiding rabbit holes too deep.
People who enjoy programming and long stretches of mental exercise are rare, and have been rare throughout history.
I didn't get into tech by a boot camp or something I was originally in phys/eng but picked up building LAMP websites on the side. Took me like 3-5 years before I actually made money from writing code.
An aside, but I am truly concerned that our path from working to professional class via tech work is closing up behind us.
I think the key is the understanding that programmers are are properly paid for their work, and now we need to make sure teachers, janitors and garbage men and the like get to have good, stable lives. And yes, I think janitors and garbage men should make as much as programmers.
Yeah I'm not sure about that, although I heard like in NYC some garbage men make close to $100K.
I still believe in proportional compensation based on effort eg. a doctor otherwise why try.
Most people when seeing my paintings are quite surprised to find out I rarely sell them. It's because as soon as I try to professionalize that part of my career I have to change what I'm doing to fit a market, and I hate everyone else's taste but my own.
P.S. some of my paintings can be found at https://lnsy.studio, but mostly I write software for organizations that work on dealing with the climate crisis.
https://twitter.com/buttpoems/status/1335423879238455299
I started drawing as a hobby when I burned out in my academic career some years ago. I don't think I'm any good at it, but every once in a while I get an offer to do paid artwork. So far I declined all of them because I felt that would make me lose the relaxing escape from my day job.
That said, IMO this is also a clear case where HN’s title editing is misleading. A common format for this might present somewhere between 5 and 20 facts, and someone familiar with these edits would likely assume that. Seeing the actual title made it feel as if the edited one is, in reality, the true clickbait.
Guerilla warfare is pretty effective, just look at the CIA's ability to reshape the geopolitical landscape!
https://www.goodreads.com/en/book/show/140167.Life_Paint_and...
A developer usually has 0 power of voice, and knowing how things can be done a better way is not helping: you can't convince management to change approaches unless you are part of it.
As a personal note, I did web development as amateur since 1998, and as a day job in 2009-2016. After that, it was clear that the industry became a huge factory where you constantly screw the same kind of nuts on a conveyor belt.
Out of factory web development, you could do simple project sites for small local business or NGOs and their events/projects, but that meant tinkering with Wordpress plugins and very low pay.
Lol! Software developers that care about customers. That'll be the day.
PS: as an evil agent I know write code at every min wage gig that involves computers. 10x increase in productivity. Direct service to the people. Heh
People are people..
Also, even the best programmer will make really stupid mistakes that may break everything.
Also, the best programmers in your team are prone to starting a fight over BS, because they tend to have a very strong opinion.
It's too simplistic to want only the best programmers in your team.
I disagree with this one in some scenarios. Replace "everybody on the team" with "your prospects and users".
> Everybody has small screens, and they all know how to scroll: only make UI widgets ‘sticky’ or ‘fixed’ if you have to. They know where your navigation bar is. You don’t have to push it in their face the whole time.
True, true, true.
I love abstractions and I love tools, especially those that need to be invented to help people do better work namely the devs.
I transformed our FE area (ca. 200 devs) into working with a self-developed platform on top of a framework. We rely solely on Angular since 5 years now and never looked back. (Why not React? Try to develop large apps with many, many teams in different countries with different skill sets 24/7: opinionated for the win. React is like C while Angular is more like Java or Python in this case. Great tool, but people are the "problem".)
Results? Highly reusable complex components, a No Code Editor on top of it - and highly motivated FE devs which can work on projects or on the platform, depending on their skillset and motivation to tackle more complex problems.
Why? Because I've been where the author has been many times as a dev and as a Manager this is what I did: Do not repeat the process mistakes over and over again.
These lists are helpful and entertaining, but the damaging friction typically too often comes from the outside
Exception to the second rule of SPAS: Users will always test your history management properly.
> If the user has big screens, make use of them. When you have space, opt for detail over decoration, data over branding, buttons and navigation over menus.
So many sites are just designed for the tall, but narrow, screen on phone, and don't make any attempt to utilize a 27" wide screen monitor.
There really is something in knowing that even if you screw up somewhere it will all be gone by the next click. I mean, of course the job is difficult precisely because there are a lot of details to track, but what if you actually shouldn't if you don't really need to? I work on a product that definitely does not need to, and the amount of time we spend of bug fixing compared to our pre-SPA days is mind boggling. So we can spend a lot of time on making ourselves better developers, which is good in general, but do we need to if our product is really simple?
Btw, painting is really fun, you should try it :)
nothing wrong with that
But author fails to apply it properly to SPAs - SPAs are great tool - problem is that people use those wrong. They want to put ALL of their screens into one and build those too big. I find it useful to use SPA framework when I have one screen and multiple interactions/popups/elements that need to be manipulated in the same context. If it is different contex then it probably should be a different app for working in that context.
These lists are helpful and entertaining, but the damaging friction typically too often comes from the outside.
Painting is not that easy, and highly-regarded painters tend to have mental health problems. Some even self-mutilate or attempt suicide.
https://artsandculture.google.com/usergallery/the-connection...
> Only use the ID selector in your CSS as a last resort to fix
> extreme and hard-to-solve specificity issues. Try doubling up on a
> class first. .class.class is a valid selector and can work wonders.
Someone is going to have to justify this. What does .class.class do, and how could that be better than #id?It selects elements with the class `class` that also have the class `class`. The example might be a little abstract but it could be something like `.message.highlight`, which selects all elements with the class `message` that also have the class `highlight`.
Classes are for classification, IDs are identification. For styling you almost never need identifiers because that is not what styling is about.
<div class="message highlight">
.message.highlight {}
is much better than <div id="highlightMessage">
#highlightMessage {}
IDs are like singletons: not reusable.Another great post I found on his site after reading the OP: https://www.baldurbjarnason.com/2021/what-do-i-need-to-read-...
Love the phrasing and idea of a design "representing" complexity accurately.
I’ve seen this time and time again and it is such an easy thing to get right at the start of a project.
Then the first 5 doesn't make any sense...
Yay!
Glib answer: the goal is to provide such an absurdly long list of facts you should know, as performance art to demonstrate the burnout pressures inherent in the work.
Having no control over half of the time you spend awake is mind numbing.
<!doctype html>
<style>html, body { width: 100%; height: 100%; margin: 0 }</style>
<canvas style="touch-action: none" id=c></canvas>
<div id=z style="position: fixed; left: 0; top: 0"></div>
<script>
c.width = window.innerWidth;
c.height = window.innerHeight;
var x = -1, y;
var ctx = c.getContext('2d');
c.onpointermove = ev => {
//var p = Math.pow(ev.pressure, 3) * 20; // both bad;
var p = 0.5/(-Math.log10(ev.pressure)); // try one
z.innerText = ev.pressure + '\n' + p;
if (x != -1) {
ctx.lineWidth = p;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(ev.x, ev.y);
ctx.stroke();
}
x = ev.x;
y = ev.y;
}
c.onpointerup = () => x = -1;
</script>
I also learned about the concept of pressure curves, and that they're really annoying both to implement and to get right: https://github.com/xournalpp/xournalpp/issues/2619, https://github.com/xournalpp/xournalpp/pull/2622, https://github.com/xournalpp/xournalpp/issues/1170The two one-liners above to convert pressure to lineWidth are the result of playing around with no idea what I'm doing for a few minutes. They... work, in the sense that I can tolerate them for about 30 seconds :) but I keep playing with them because they don't "click". I wouldn't mind suggestions for how to actually do this (my google-fu isn't finding anything, likely because I don't know what to look for). I had a poke around Krita, but only found C++ abstractions.
I also stumbled on http://willowsystems.github.io/jSignature/#/about/linesmooth..., which is an awesome looking bit of open source code. It implements both realtime curve extrapolation and pressure approximation for devices/environments that don't report that.
>They already regret having to use your app; don’t make them regret you were ever born. (Too late! Hah!)
"Someday, everything is gonna be different, when I paint my masterpiece."
-BDylan
(*TOP* (@ (*NAMESPACES* (x "http://www.w3.org/1999/xhtml")))
(x:html (@ (xml:lang "en") (lang "en"))
(x:head
(x:title "Seriously?!"))
(x:body
(x:h1 (@ (id "hwat")) "No.")
(x:p "I have never heard of this before and am not sure if I ever want to interact with it again."))))