I periodically think "Man, I really shouldn't be getting paid for this. Any idiot could stick these two APIs together."
In my more sensible moments, I remember that that idiot only needed to know HTML, CSS, the DOM model, Javascript, jQuery, HTTP (mostly headers and status codes), Ruby, Rails, basic MVC design, Oauth, SQL, SQL performance, five-ish APIs to support the two that needed integration, how to configure and maintain a server, system architecture, a bit of security, etc.
[There's also object oriented programming, class inheritance, polymorphism, algorithms, time complexity, discrete math, data structures, imperative programming, and a few other things I forgot the first time around. Lest we forget, we might take these for granted because we've been programming since we were $ARBITRARILY_YOUNG, but to most people these are just black magic. My girlfriend, a smart cookie, asked to see "how I made the phone ring" and, after I showed her the code that did that, told me it had never even occurred to her that every program she's ever seen was once a collection of special words placed in a particular order.]
After that, it was pretty much done, except for the marketing.
On the plus side: you can learn one or a few of these things at a time, and get more comfortable with how deep the rabbit hole goes as you go along. I coded my website in static HTML written in Notepad with no JS or CSS, crikey, only four years ago. (And my brain still recoils at how much better I'd have to get to do e.g. web scale work.)
It's like maintaining a skyscraper built out of Tinker Toys.
What I wonder is: Does the following sentence run through the head of every expert in every field?
Man, I really shouldn't be getting paid for this. Any idiot could [do X].
It certainly felt true of most of my day-to-day work in graduate semiconductor electronics. It felt true of a lot of biology research. My conclusion is that there are a mere handful of days in your career when you will have to do something so hard that you will feel smart about it. But most of your career as an expert will be spent doing stuff that you know so well that it's kind of routine, even if it is totally esoteric stuff that only you know how to do.
Feynman said it well when he teased the mathematicians: "Mathematicians can only prove trivial theorems, because any theorem, once proved, is immediately seen to be trivial."
Man, I really shouldn't be getting paid for this. Any idiot could [do X].
Another variation: what I do is not easy but every person practicing in my field can do this just as well as I can.
I worked very hard for many years to master my craft and always felt deficient along the way because the individual pieces seemed so daunting as I encountered and dealt with them. Not daunting in the sense of insurmountable. Just difficult. Long hours, Lots of sweating it out to get a given project done, one step at a time.
Nothing new here. Everyone who works hard to try to excel in his field goes through it.
It took me 10 years into my career to realize that many in my field (law) were not like me but contented themselves with cutting corners or otherwise coasting along while seeking to avoid the hard challenges.
Doing something right, and learning to do so consistently, is hard in any complex field. It does seem easy once you have mastered the difficulties but not that many are willing to do what it takes to get there. People are all too often content with mediocrity.
"It took me 10 years into my career to realize that many in my field (law) were not like me but contented themselves with cutting corners or otherwise coasting along while seeking to avoid the hard challenges."
I remember going through that moment. It puts the quantity of "best practices" chatter into perspective. People say this stuff over and over because it seems so widely ignored.
"It's like maintaining a skyscraper built out of Tinker Toys."
Actually, it's like maintaining a skyscraper built from steel, concrete and glass integrated with complex HVAC, plumbing, electrical and elevator systems.
This is also true. But it's a question of levels of abstraction. The skyscraper is built out of (in part) a plumbing system, the plumbing system is built (in part) out of pipes, and assembling pipes is like assembling Tinker Toys. Which is why we give a five-year-old aspiring plumber a set of Tinker Toys to learn with. [1]
But this is only a few years after the web was invented, and the average website is still sufficiently ad hoc that the Tinker Toy level is a lot more visible.
---
[1] Break any human-designed system down far enough and you'll often arrive at something as simple as a Tinker Toy. Although, of course, Tinker Toys are not that simple, so this fact may not help as much as you'd think. And this is not true of all systems: In metallurgy, the "simple" parts are atoms, quantum mechanics is not like Tinker Toys, and even if it was nobody has experience with a Tinker Toy set containing 10^28 pieces.
"Actually, it's like maintaining a skyscraper built from steel, concrete and glass integrated with complex HVAC, plumbing, electrical and elevator systems."
Adding, "Designed by a committee. Of MC Escher fans."
Two different development processes, two different outcomes. And unlike other 'construction'-type businesses, in software we have many different development processes.
Man, I really shouldn't be getting paid for this. Any idiot could [do X].
I definitely think that periodically about technical translation. Any idiot could read some text and type the exact same text. Then I remember that not everybody can read German, French, Spanish, Italian, and Hungarian, and still stay focused on being able to write readable English.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision.
> Does the following sentence run through the head of every expert in every field?
> Man, I really shouldn't be getting paid for this. Any idiot could [do X].
That's because most experts are humble. That is what allowed them to become experts in the first place.
I think the comparison was with embedded programming, which can be pretty hard in its own right.
Also, with lots of embedded stuff, you don't get the "do over" of being able to update your server with the latest code. Once it has shipped, it had better work. In some cases, people's lives may directly depend on it, something that's probably fairly rare in the world of web programming.
I'd hire someone good with C pretty quickly, if I had the time to let them get ramped up, and they demonstrated the flexibility and willingness to learn.
I hopped on your website, sir (madam ?) and no doubt, you are a rockstar. I'm talking about typical jobs -- typical embedded vs. typical desktop vs. typical web. Yours does not seem like a typical job, nor do you appear to be a typical developer. Most typical desktop/embedded jobs out there do not require keeping up with constantly changing technologies the way typical web jobs do.
My husband's just starting to get into web development in the hopes of being able to do it with me in a few months. He's a C programmer from years back and has a great head for sorting out and designing how an app should run. His theory is solid, and he has real programming experience to back it up.
I've been bringing him up to speed on the web stuff, though, and he's said the main thing that gets him is that he can't just learn a language and build an app. He's got to learn HTML, CSS, JavaScript (the DOM, jQuery), SQL, PHP/Ruby/Python and any accompanying framework we choose to use, etc. and piece it all together.
It's not that he finds any one of them particularly difficult (he's picking up on them quickly), it's just that there are so many pieces to the puzzle that all need to be understood and fitted together (and they often inter-mingle so much that you can't always separate them out and do one, then the other). It's just a large and varied volume of things to process.
I bet 90% of the time, any "expert" is working on things that any idiot can do. But that isn't why people pay experts!
I think experts are paid so much because of the other 10% of the time. When convoluted edge conditions have made a mockery of all things abstract and sensible, they are capable of diving into the black boxes and figuring out what's really going on to save the day.
A good friend of mine is a master carpenter. When I need something done on my house I'll always hire him or his equivalent in electrician or plumber. And it's mainly because I just want the peace of mind of knowing the job will get done properly. He charges a lot but things always get done quickly and without hassle.
I've watched other home owners I know try to do things on the cheap and they're constantly getting burned. Things take longer, there are unforeseen problems and jobs quickly develop into hassles. If you can't afford to do it properly then just don't do it. And if you can't afford to hire the right person for the job then don't hire anyone.
As a cheap programmer, I disagree. An expert may spend 90% of his time doing something he feels is drudgery, but he does it properly, so as to prevent the 10% all-hands-on-deck emergencies from occurring.
If you hire cheap programmers to handle the 90% under the expert's supervision, the expert still has to painstakingly review the work so as to ensure it was done in a way that at least sort of resembles the method the expert himself would have used. And having reviewed other people's code, I am of the opinion that process is sometimes soul-crushing.
As a cheap programmer, I appreciate the consideration, as I like to feel I have some utility. But as an entrepreneur, I think it's a bad idea.
As a not-so-cheap (by local standards) programmer, I'd have to agree with this assessment. Sometimes, customers will ask if it's possible to reduce the budget for a contracted piece of work by getting some of their internal staff to do parts of it. I've tried to make this work, but it basically doesn't in most cases, for the reasons you mention. On the occasions I agreed to try it, it would have ended up more expensive, even when assuming internal staff time to have a cost of zero. Fortunately I agreed to try it only on the condition I could bail out and do it all myself if it wasn't working. Which I did.
I realise this may come across as me being arrogant or unable to work in a team. I can't with good conscience pass judgement on the former; I am however frequently contracted as an extra brain and pair of hands on projects with people of comparable skill who could do it without me, save for the project's time constraint. This generally works very well.
It's conceivable that the model might work if the skill gap isn't so big. Presumably that makes the programmers less cheap, and the scheme less attractive. Plus, they could probably muddle through without me, thus never feeling the need to hire me in the first place. Which, I assume, is why this has never happened to me.
I concur, a sort of an apprenticeship program would be quite useful. If an expert can guide 1-3 people to do most menial tasks, it would serve the dual purpose of getting stuff done and educating a lot of interested people.
Currently we have university projects, internships and the like. However those are often slow to react to technology changes, or are too rigid and lacking proper employee orientation procedures.
It is a nice pipe dream to have a sort of a board where one could find a mentor in a particular subject, while working on a real-life project that shows all the dirty stuff that most undergrads are sheltered from before they enter the job market. E.g. topics of the "I'm doing a Django project and I could use some slaves to do this, this and that" sort.
Being a web-programmer - those C and GUI stuff looks hard to me. The grass looks greener on the other side, the tech looks harder on the other side. I am humbled too.reply
It's interesting, I definitely see myself thinking the same thing (which may lead to myself undervaluing my skills because "any old dummy!" can learn this stuff). There are days where I've joked where I'm a "glorified typist" :)
I think in order to become more and more skilled you tend to abstract certain things out and take them as a given. Basically you know how things work, you just never think about them.
I remember when my company had an intern, and his only real education was college based (he hadn't really worked on any of his own projects). I had to explain how our stack worked, and generally these are a given when you're working with the stuff. But to someone who has never worked on this stuff it's very odd and unfamiliar. I also think that in order to build a good product for someone it helps to get to that point. I don't really need to spend a lot of time thinking about implementation these days and can focus on what would make clients happy.
To users, this stuff just works and I forget that sometimes because I'm in the weeds.
Integrating various python modules/ruby gems that all monkey patch over each other?
ducks
On a more serious note, the closest equivalent I can think of is porting games to work on windows, linux and mac platforms. You would have to have a good understanding of the entire renderer, any main event loops and physics, as well as experience in writing very low level code on all those platforms.
Yes, this would be very challenging. Making games cross-platform is not the typical GUI app out there, and is not the sort of app I was thinking about on my blogpost.
You forgot the architecture needed to sustain a development enviornment - the VCS, bug tracking, deployment (ssh? shell scripts? something more modern?), and so on. But that's probably because it's all so obvious.
I've always been a hobby programmer, but over the last few months I've been developing some web sites and trying to bring my skills up 'to the next level'. The things you mentioned- vcs, bug tracking, deployment- are definitely non trivial. Partly because while most programming languages are well documented and have lots of tutorials, the things you mention are almost a black art, something every programmer does a bit differently (I think) and rolls their own scripts.
For example- there is a php project I want to contribute to with bug fixes. I can fix the bugs no problem, but submitting a patch & using the bug tracking system? Way beyond me!
VCS and bug tracking are not difficult. You can get it all by just installing fossil. If that's not your thing, you can install tortise hg (on Windows) or some other dvcs and get started in next to no time.
Deployment is definetly ugly. There's stuff like pip, fabric, and virtual-env (all on python) which are meant to ease the pain ... but the fact that agile geeks reccomend 3 different frameworks just to make things simpler show how ugly it is. I don't know what the cool kids use for PhP though.
"only needed to know HTML, CSS, the DOM model, Javascript, jQuery, HTTP (mostly headers and status codes), Ruby, Rails, basic MVC design, Oauth, SQL, SQL performance, five-ish APIs to support the two that needed integration, how to configure and maintain a server, system architecture, a bit of security, etc."
You should talk to my new boss, who just tore a strip off my ass for not getting somethings done in 3 days, that took another team in the company 3 months. Oh, you just have to "do this", no problem. Invoke Magic, upon 10 year old hardware.
As a web developer I appreciate the concession from an embedded systems programmer that I am in fact not simply a monkey, but the quoted section probably goes a bit too far.
For instance, terrible UIs on the web are just as common as terrible UIs in GUI applications. And making a cross-platform GUI application that looks good on all platforms requires familiarity with tools specific to each platform, which is much more involved than learning browser quirks.
The hardest thing about the web is probably how fast it moves, but that's also what makes it exciting.
I did C and C++ programming for more than 10 years, before suddenly delving into serious web development only 3 years ago. I soon realized that I had vastly underestimated how deeply technical web development is.
But the reason was simply that I had formed my opinion back in ~1998, when "web development" really did mean just HTML, and maybe some roll-over script, most of the time! Being a systems programmer, I simply never had occasion to update my perception, as "web development" dramatically evolved while I wasn't looking.
I am not sure which particular flavor of "embedded" the author is referring to, but the argument, in my view, is completely off the mark, and here is why:
The main challenge of embedded is that you are in charge of controlling and managing everything. The developer is closer to the hardware and the cost of things breaking is far higher because you cannot for one second forget about some part of the technology stack that's below you. Everything is suspect, and nothing can be ignored.
On the web, you get used to your automatic garbage collection, your GUI toolkits, your nice browser sandbox with infinite memory that gets automagically replenished, your in-browser JavaScript debugger and all that jazz. You get to enjoy none of it in the embedded systems I've worked with.
Fixing embedded systems in the field is freaking hard, so the quality of code matters is in a completely different dimension from what's on the web today. Now, I am not talking about Linksys router or your iPhone. That's just a fraction of "embedded" devices. I am talking about things that don't have a TCP/IP stack (or any connection to the outside world), don't have a GUI, and are installed at the contractor rate of $1,000/hr and must exist in the field for 10-20 years. There are millions of these devices shipping every month, and they are all around us.
Are you telling me these systems are easier to design than a webpage that can be twiddled with at your whim a million times a day?
Don't downvote just yet! Just so you know where I am coming from:
I am a product manager for a 100K LOC embedded stack that runs in 128K of flash and 8K of RAM. It's all C code, no OS, no toolkits, no MMUs, no garbage collection and no dynamic memory allocation. These devices get 15 years on a single battery and go inside your house. I've also had good exposure (not an expert) to the online technologies the author mentions. Yes, things may be tough to learn (I don't actually believe they are), but the web is a lot more forgiving of mistakes too.
You have a point. Sure, embedded problems can be very tricky and difficult -- much more so than web stuff. But most embedded folks don't solve problems of THAT complexity in their day jobs, just as most web programmers aren't implementing Machine Learning code during their day jobs. The embedded problems you're discussing are usually tackled by the elite, or by highly specialized Linux kernel types -- and no, I'm not elite. Many employed embedded people, believe it or not, have never worked with DMA.
I work for an embedded company doing web development and tool chain support for the embedded product. So I kind of have my feet in both buckets as it were.
You're right in that the main difference is control. In the embedded world the developer has total control over everything. And the specifications for the product are very well defined.
The problem with the web world is that the specs are terribly defined or ignored and you depend on APIs that constantly change. Not having to worry about memory management is great in the web world. But instead you get to worry about how your page will render in 5 different browsers that each have decided to only partially implement some standard. At least in the embedded world if a piece of HW doesn't conform to spec it's defective and gets replaced. And you know exactly what that spec is.
I don't know which is worse. Being forced to write everything yourself or depending on the sometimes mediocre code of others?
No doubt, your embedded world presents incredibly difficult problems -- arguably much trickier ones than most web jobs out there. Keep in mind, as the OP and author, I'm comparing the "average" embedded job or desktop software job to the "average" web job. Perhaps I should have made this distinction clearer in the blog article. Most employed embedded engineers do not work on problems as tough as the ones which you describe.
But to me, the biggest challenge with web is the unforgiving avalanche of emerging new technologies a practicing professional must keep abreast of, literally during every spare second of their life, if he or she is to remain employed !! This unrelenting blizzard of new algorithms, new languages, new frameworks, new design methodologies is just another typical day in the life of a highly competent and employable web engineer.
The resource-limited embedded problems at your company are "old school". I'm not saying they're easy, but do the tools and technologies needed to solve such problems change much through the years ?
One common mistake when one tries to tackle the web is to do it all at once. What you need:
- get familiar with HTML and css. That is, learn the basics, their purpose and how they interact.
- get familiar with some basic JavaScript and how you use it on the browser.
- learn one of the prominent web languages for the server-side. Python, Ruby, PHP, etc. I used to recommend PHP as a first language because compared to other languages, it was ubiquitous amongst hosting providers. Nowadays, I recommend against, especially if you already have some programming experience. Python and Ruby also have a decent offering and they have the added benefit of a community that generally promotes better programming practices than PHP.
Having an overview of the entire development process, you should now be able to pick one area where you'd like to expand. Being a programmer I suspect you might pick either server-side or browser scripting (JavaScript). Stick to one at first and learn it well. When I started the web I rarely did any front-end at all. I concentrated on the server-side and was aided by some CSS and JavaScript coders. Likewise, I often worked with JS programmers who didn't want to know anything beyond the realm of what they were doing. It's a symbiotic relationship.
- It may be tempting to do everything vanilla at first, but quickly switch to using a framework, they're often packed with lots of best practices. They're like training wheels, you can always take them off later when you feel confident.
As you get comfortable with one field you can expand on others. After years playing in the server, I'm only now expanding my client side skills. Also, beyond technologies, other areas of interest that can expand your overall understanding and web expertise, are interface architecture, usability and various other optimizations. As you go, you'll stumble upon many.
That said, you need to have a firm grasp of all the basic security concepts before rolling out production code. You need to know how to avoid all the various injections.
There are some pretty (free) good tools out there to test against most injections methods. I'm not saying having a conceptual grasp of security hurts ;)
All in all, you can't know all methods - and the tools won't probably know much less.
Every security professional I've heard speak emphasizes the importance of grasping what they tend to call "the security mindset". Which I understand to mean putting yourself in the place of an attacker and asking how your code could be taken advantage of.
Running an automated tool against your web app isn't a bad idea, but it's no replacement for thinking about what you're doing.
For the less technical it sometimes helps to qualify what something is even if it is embedded in the abbreviation. But considering the audience here, you're right. I will remove the offending word.
I've seen a number of times when people don't understand the statelessness of HTTP, and try to put megabytes of data in a cookie-backed session--unable to understand why that doesn't work, etc.
This is especially prevalent in .NET land, where there are mechanisms for storing data in hidden forms and hiding the statelessness away from the user.
Why is that a costly mistake? REST is great but it's not the only way to do web development. Read up on continuations, for example. In fact, this very website is using continuations (check out how paging works) and it doesn't seem like a costly mistake.
Yes, it's hard. Unnecessarily hard, which is why I hate when I have to do it.
The complexity of web development is not intrinsic to the problem, but an extrinsic reality imposed by widely differing implementations of a number of overengineered technologies.
Well, if you expand your definition of "the problem" to "how do we enable people all over the world to interact with this information on any computing platform over an untrustworthy connection running on low-end hardware", then I think the chaos and technology soup is a little more necessary to things being where they're at now. So no, it's not technically necessary, but politically/economically it is.
First, she thought implementing a linked list during an interview was hard. Then, she says that web programming is hard. And I'm not saying it's "easy", but talk about blogging yourself into a professional grave?
Personally, I find it refreshing to read a blog post that isn't - either directly or indirectly - about how amazing the author is.
Programming blogging has a strong culture of focusing on the newest, shiniest, and cleverest; the only negative blog posts tend to be "why X is wrong". No one blogs about their difficulties, weaknesses, doubts, or the huge amount of effort it takes to get really good at something. I think that's unfortunate, because it paints an inaccurate image of programming.
I never said linked lists were hard. I said that it's not necessary to know how to reverse a linked list from memory -- from scratch. I can look it up and get to it right away.
You know, at one point I thought that as well. I felt, that as someone who programs almost solely in 1) C# 2) Erlang -- "thanks I've got a stdlib for that".
And then I actually thought about what it takes to reverse a linked list for a second.
And immediately realized I will never, ever hire someone who can't regurgitate or reason how to reverse a linked list "from scratch" within a few minutes.
I'd go one further - if I thought somebody was giving me a rote answer for how to reverse a linked list, I would push them to see if they actually understand why it works. Or switch to something a bit more exotic, like a skiplist or radix trie, and see if they have any intuition about data structures.
I just went through this exact same process reading your comment. "Well, DSA was a couple years ago... I don't know if I could answer that right off the bat." "Come to think of it, how would I answer that?" "Oh, it's completely obvious."
Not that I expect to be in a position to make hiring decisions, but if someone can't answer that intuitively with a few moments' thought I know they're probably a couple of years' experience from being able to keep up with me.
1) That's irrelevant. I'm speaking to the importance of the ability to reason a linked list which is not really related to 'practical examples of linked lists in a web development context'. To quote silentbicycle above: "It's a linked list, people." We're not talking about 'the latest developments in red-black tree algorithms'.
However...
2) Probably every list of objects you throw around in whatever abstraction providing framework you're using.
Would you hire somebody who can't compute 2+4? For the same reason you wouldn't hire somebody who can't reverse a linked list, even if the actual reversing of the linked list doesn't come up in the job.
Why a linked list? Wouldn't something resembling a hash table or even a tree be a lot better.
I think with web development a lot of the situations where you would want a linked list are abstracted away. Personally I would be testing people on how they take some kind of design outline and map out how they would approach it. Something like dealing with bringing together multiple API's to would be high on the list, this is becoming a much bigger part of web development.
But on a whiteboard? That they then take a photograph of? Please! Let me pull out my computer and I'll TDD it for you right there. I coded doubly-linked lists in assembly language at age 15 without ever reading about them, but I can't spew it out onto a whiteboard.
Fair enough. But as someone who's conducted hundreds of developer interviews, I can say it's absolutely a huge red flag for me. Total failure would be a straight no-hire. I see it as something that should be very easily re-derivable. You certainly will encounter harder things that you need to invent (not just re-invent) during the course of any job.
You're defending your honesty, but your honesty isn't what's being attacked; it's your competence.
I've been asked in interviews before, how to reverse a single-linked list, and impressed interviewers with my answer to this seemingly trivial problem; but I also remember when I first met the problem, in a newsgroup posting nearly two decades ago, and I had temporarily convinced myself it couldn't be done in constant space. But then I saw the problem as pushing and popping of stacks: view the old list as a stack to be popped, and the new list as a stack to be pushed, and thence the list shall be reversed.
But doing it elegantly - in constant space - is besides the point. Reversing a linked list is a problem which can be solved, even clumsily, without much thought. But demonstrating problem-solving in an interview situation, that is the point.
Perhaps I've just worked with linked lists too much at this point, but I find it nigh impossible to understand how reversing one could be considered even minimally difficult. "Pop the head of the source list and prepend it to the target until the source list is empty." One sentence, no complex concepts involved at all.
If it's unfair to expect someone to answer a question like that in an interview, then I'm not certain what is fair. In a world where people with literally no programming skills whatsoever regularly apply for programming jobs, I need to apply some filter to weed out the incompetent. Sad experience has told me that educational credentials and claims of past work experience are insufficient.
It's very hard for you or I now, to appreciate what it was like before you learned to think of linked lists as stacks. The point is, there is definitely a leap of insight necessary if you've never thought of things in this way before. I was 12 or so when I made the leap, and I guess I'm slightly lucky that I remember the exact moment for this particular case.
I don't think I knew what a linked list was at age 12, but I don't think you even have to know what a stack is to do this. Just draw it on a whiteboard, and it becomes obvious that you just walk the list and flip arrows. Seeing that linked lists can represent interesting structures is I think an even more advanced concept, but one that is unnecessary for this particular question.
I really have a hard time believing that coming from a C/C++/embedded background you couldn't whip up something reasonably workable (linked list) in 15 minutes on a whiteboard. It's usually the people that have gone on to become "architecture astronauts" who can't do it, or the people who could never do it in the first place. I mean it's as much a test of passion as a test of competence. You can see that certain people are physically pained by writing code. They just don't enjoy it and want it to stop. Other people are engaged and clearly want to produce something. Even if their result isn't perfect. If they are verbalizing something relatable as they get stuck on the same stupid ha-duh mistakes you get stuck on when you do your own job day in an day out. For the people who I think are exceptional, this should be refreshing to them, almost nostalgic. No need to worry about browser compatibility of your linked list, no need to worry about its latency, its availability, making a mobile version of it, etc etc etc. It should just be "I haven't done anything this uncomplicated in a long time." Maybe you should just bust out notepad (no compiling!) and try it and time yourself. Without the pressure of someone staring you down, maybe you'll surprise yourself.
I don't know what to say guys. I'm not incompetent but if you want to assume that I am, then I cannot stop you from drawing those conclusions. Let me say this : it's not a matter of comprehension. It's a matter of performing flawlessly under pressure at the whiteboard.
This is getting to be a really silly off-topic discussion, but I have to admit, I would be totally curious to hear if you could identify what is difficult for you about this task:
A) Pressure of an interview situation makes it hard to think straight?
B) Absence of familiar IDE, environment, REPL/compile-run cycle makes it hard to work or think effectively?
C) Something else?
I just don't see how it could be difficult for someone who understands loops and pointers (as I assume you certainly do.) I would have filed "reversing a linked list" under the Fizzbuzz category of things-that-anyone-who-has-ever-actually-programmed-can-do.
I am not a stupid copy/paste programmer who doesn't know what the fuck she's doing. Trust me on that. As my blogpost said, I thoroughly understand the concepts. But if you read my blogpost comments, you'll notice that many people sympathize -- and I doubt that these people are incompetent. Some people will impress at whiteboard coding, others will not. That's it.
When I first started programming I was doing VBA on spreadsheets. I thought entirely in terms of simple commands, variables, events, if statements and the occasional loop. I could vaguely remember what an array was from highschool but never needed one (although, to be fair, I had a spreadsheet to work with).
I did not have a clue about objects, classes, pointers (Pass By Val vs Pass By Ref was like flipping a coin), never mind linked lists. But despite this, I managed to get a lot done. Of course since I've taken the time to educate myself I understand now, but my point is in some settings you can go quite far without ever engaging the fundamentals of computer science.
I know the OP said she does understand all that stuff but it's also possible she barely needs to use it.
Maybe it's the "computer scienciness" of the term. I'm a practical programmer with a tiny bit of industry experience, and have only just started attending university. And I'm intimidated by it all. Memory allocation! Pointers! My brain shuts down and I imagine anything I say will put McCarthy in the grave and cause Dijkstra to rise from it.
But the first time I read some blogger ragging on interviewees who didn't know how to reverse a linked list, I read the first sentence of the wikipedia article and realized it would be easy to do (albeit probably not elegantly): just loop over the list doing push/pop operations.
It's a pretty easy solution, and already runs in O(n) time, so I'm not sure why I doubt myself. It's probably that although I'm used to devising solutions for complex problems, I'm unused to problems that are formally defined.
I think that sounds like probably a big component. I do know what you mean -- something about the words "linked list" seems complicated, even though there's nothing much simpler than an actual linked list.
I wonder if people who would freeze at a question about reversing a linked list could answer that and similar questions if they were turned into "word problems" somehow; e.g. evilduck in another comment compared it to reversing the order of charms on a bracelet. Although I can't think of any examples that doesn't sound terribly contrived.
Of course it's doable. Like I said on my website, I need to get off my ass and start coding up linked lists, binary search trees and sorts "til I fucking throw up all over Manhattan". Yes, of course it's doable. I'm no dummy. I can stumble through it on the whiteboard as well -- I'm not deaf, dumb and clueless -- I don't just stand there at the whiteboard listlessly, with blank stares, if that's what you mean. If I practice enough, reciting from memory (and on the whiteboard), coding the stuff up perfectly will be trivial. But to me, that's gaming the interview.
Rather than memorizing stuff forever, you could develop your intuitions about data structure design trade-offs and what makes them behave the ways they do. After I learned OCaml, a lot of data structure design seemed obvious.
Also, read _Purely Functional Data Structures_ by Chris Okasaki. Unlike (say) CLRS (http://mitpress.mit.edu/algorithms/), it's even a pretty short book.
Exactly. The OP thinks that when I ask her to reverse a linked list, I expect her to whip out the perfect code from memory on the fly. I would be even more suspicious if you did that actually. I want you to structure the data. I want you to try out variants of reversing. It is ok if you can't give me the optimal solution in 5 minutes, as long as you demonstrate the capability to reason with data structures and pointers and tools at hand.
I'd actually recommend not reading Chris's book in isolation. There are a lot of things that are ugly to do in functional languages (w/ respect to data structures), but are easy with assignment (and of course vice-versa). I'd read Chris's book with Sedgewick (Sedgewick is a super applied algorithms text). This will help give a good balance.
I partially suggested it because it uses SML for the code. Even if one doesn't use OCaml / SML for actual programming, using the notation will probably help quite a bit with reasoning about data structures.
When encountering problems where I have to derive the answer without a crutch, I solve most by thinking how to solve them either through native language or spatial movement of object, then translating into code.
How would you reverse the order of charms on a bracelet? Any time a step isn't clear, break it down further.
> Any time a step isn't clear, break it down further.
And that really is the key to programming. Which makes pretty much anything solvable from scratch. Whether or not you'll come up with the most efficient solution (or at least one that runs reasonably fast) is another thing but at least you'll come up with something, or at a minimum a well defined little black box that you know you're going to have to fill based on the name you gave it.
Sure; but there are a ton of places they can get a job as a "programmer" having only interviewed with a non-technical manager. These people become experts at this type of interview and are able to do what I call, "dazzling with bullshit" quite effectively.
I think I understand what you are trying to say. Maybe you need alternate examples to show what you mean:
Scenario 1)
------------------------
You have 2 candidates 'A' and 'B' in a team. 'A' is actually better than 'B', writes better code, and has the ability to debug issues which 'B' really can't get a handle on. Both
get a call to interview for a company in 2 weeks. 'A' has confidence in his/her abilities, so just goes through an algorithms/data structure book and writes 0 lines of code
in the 2 weeks. 'B' on the other hand, buys couple of programming interview books, goes through common questions (like reversing a linked list) and actually practices coding these questions. On interview day, 'A' is posed a question to merge 2 sorted linked lists. 'A' hasn't worked with linked lists for some time now, takes some time to come up with an answer, and writes up a solution on board that has some syntax errors. The interviewer had other questions to ask, but has no time because 'A' took a lot of time to code this one. ('A' has a cold start, so to speak).'B' when posed with the same question solves it within 15 mins (what with all the practice) With that confidence, 'B' aces the rest of the interviews. 'A' is kind of disturbed, cannot believe linked lists can be so tough, and does OK in the rest of the interviews, but still doesn't exude the confidence of a person who knows his stuff.
No points for guessing who is hired.
Scenario 2)
---------------------------
Instead of short interview times and questions about what everyone calls 'basic data structures', lets say both were given laptops during the interview and were given a program/requirement that neither had seen before and something that did require logical/analytical thinking to solve. Say, instead of 40 mins they were given 2-3 hours to complete the coding/debugging with access to a compiler and to language/API documentation. Who do you think would do better? (If it is not obvious, I back 'A' to do better)
I would really say scenario 2) is a better simulation of actual working conditions. Unfortunately, most interviews are like 1), maybe because 2) is more work for the interviewer. (logistics + framing a good enough problem)
OMG, blink1729, you read my mind. I couldn't have said it better ! Someone from salesforce.com (who I met via HN) told me that software folks are interviewed similarly to Scenario 2)!
It may not be necessary, but a competent developer should be able to do it in their sleep with one hand tied behind their back. If a candidate finds it difficult to do so, that's a really bad sign that they'll find the necessary things difficult as well.
As someone who has only dabbled in web programming and done webdev-ish work at a company that doesn't "get" the web, I was in shock to see how much I didn't know that was really the bare minimum:
I've come across a few of those "bare minimum you need to know to do X" posts on SO and on one hand I think they can be great pointers to the best reference material in a given field.
On the other hand I worry that these kinds of lists promote an impractical approach to mastering a field that is at odds with being a "Hacker".
Think of it as being like Waterfall Subject Mastery versus Lean Subject Mastery. In Waterfall Subject Mastery you try to anticipate what you need to know up front, learn a bunch of stuff, then try to apply it to a problem. There are two problems with this model: First, you really don't know what you need to know. Second, you won't really understand it as well in the abstract.
With Lean Subject Mastery OTOH, you pick a problem and crank on it until you run into a wall. Then do some learning until you can overcome the wall. At first the walls will be many and frequent. But over time your baseline of competency is increased and you actually become productive in the new technology.
What's great about the lean approach is that when it comes time to learn about a specific topic, you have a much better context for understanding it, and thus the effort to learn it is greatly reduced. And because you have an active project, you can put your learning into practice more quickly and thus retention is increased.
The secret, though, to making LSM really work well is to commit to learning a bit more than just what you need to get over the wall. This is the difference between truly learning and being an eternal cargo culter. Don't just start banging against the OAuth library; try to understand how OAuth works. Just do it in the context of a real-world problem.
Don't get me wrong. I'm not against education and learning for learning's sake, I'm just more for efficiency and getting stuff done.
Another advantage of just-in-time learning is that forgetting is less of a problem. You don't have to worry about forgetting in between the time you learn it and the time you use it, and the fact that you've used it both helps you understand it better and gives you a working example to use as a reference. (Am I the only one who looks at their old code to see how they did something?)
Probably the best is to sort of skim over the stuff you're supposed to know at first and then refer to it when you're reminded of it in your everyday work. Like the breadth-first approach Steve Yegge advocates for math: http://steve-yegge.blogspot.com/2006/03/math-for-programmers...
The only problem I've found with this approach in practice is that skimming makes me antsy.
Web Programming is nigh impossible for 1 person any more.
To build a legit website:
1. Mockup a pretty design in photoshop. Use color theory, design principles, UX theory, typography skills, etc.
2. Convert the design into HTML/CSS. Make it degrade gracefully, it should be cross-browser compatible, validate, be lightweight, meet accessibility standards.
3. Add unobstrusive javascript if you want, site should work without it.
4. Run YSlow, convert all images into sprites where possible, condense/minify your JS/CSS.
5. Do SEO tweaks and best practices.
6. Oh wait, does the site display well on iPads? build a mobile version and a tablet version.
...
We haven't even gotten past the front end. Learn good db design, code your middle tier. Choose or roll your own framework. TONS of work.
Once it works, go back and secure everything for the OWASP10 and other potential holes. Also make sure it will scale gracefully.
Maybe you should optimize your cacheing scheme? Maybe tweak your php config so it runs faster.
I'm currently working on a set of SOAP web services using tomcat, cxf, mysql, and hibernate among others.
I decided to do a switch from embedded to web development about a year and a half ago after being laid off. My paycheck is smaller but I now work on a whole new set of problems. After working about 10 years in embedded and everything around it, I felt that I needed a change. It was as if I was solving the same problems over and over. And don't get me started in the state of the tools. I remember thanking the heavens when we switched platforms to PowerPC and ELDK.
At first I did not know were to start in web development. But I did decide to concentrate on the back end quite early. At first I approached each technology separately, mostly because of my ignorance. For example, I saw that tomcat was very popular, so I decided to take a look into it. But I quickly realized that I needed a birds eye view of the whole web service stack and not its individual components. At least not yet.
I started to look into frameworks. After realizing that there are lots of those and that I learn about a new one almost every week, I had to narrow my search. I've been working and learning Groovy on Grails which is all based on the JVM since then. What sold it to me was the fact that Groovy is a language very similar to Python, which I know, and that Grails is a web framework that integrates all the necessary technologies to get a decent site up and running thanks in big part to the amount of plugins available for it.
Like grayhairmomma says, it's a humbling experience.
Interesting approach to getting in to Grails. I came at Grails after about 12 years with PHP (and some Perl and other stuff too). There are a number of things I like about Grails (GORM, domain-first approach, etc). But there are still some things which bely the Java-ness of it, and I'm convinced most of the Java community doesn't "get" the web. Hard to put in to words, but an example might be:
The default in the Java world up to that point (and possibly still is) is to put a session ID in the URL. That's been frowned on and not default behaviour in the PHP world for... well since almost always. It's just asking for trouble (intentional or accidental). But the default for Grails was to have this on, because that's just how Java people think.
And the answers? Configure yet some other aspect of your system ("just change jetty's config"-type answers). Why not give more control to the framework instead of forcing people to have to learn/manage yet more systems and components. That particular issue is 'fixed' now, but there's so many moving parts that I wouldn't be surprised if it is broken again in some configurations (hasn't been for me though).
As much as I love Grails, Java as a base platform was not written with the web in mind, and makes basic stuff harder than it should be.
I did suspect that an experienced web developer will feel some heaviness when using a framework such as Grails. I'm simply too new at this to have an idea of all the little issues that arise when using the JVM.
Interesting. I'm considering doing the exact opposite (10 years web/server-side development - switching to embedded). Currently, I'm taking some extension engineering classes at UC Irvine while still working full-time.
Any ideas on where to start to get my foot in the door in the embedded world? I was thinking newbie kernel bugs and eventually Linux drivers.
The linux drivers idea is good particularly if you want to learn about communication with embedded system. But there are other approaches too.
You'll need to ask yourself how low-level do you want to go. For example:
Do you want to work on a system that has an OS, utilities, filesystem, etc such as the ELDK[1]?
Or a little more stripped down with only the OS such as FreeRTOS[2], uClinux[3], or uC/OS[4]?
Or even lower and use no OS at all. Use instead a foreground-background system--basically a forever loop.
Another way of doing this is to select the hardware first according to what you would like to do. You must keep in mind that you will most likely not have access to all the debugging tools that you're used to. This translates into very expensive compilers and debuggers for the high end hardware. But these days it seems that there is something for every taste and wallet.
Two particular development kits that come to mind are Arduino boards [5] and TI's MSP430 development kits [6]. I find the wireless watch development kit [7] particular interesting. I haven't used either.
If you see something that you like, try to find the corresponding development kit that comes with a development board, cables, and software.
A good place to start is by checking DIY or hacker magazines such as Make[8].
In most of my course work to-date it's been with no OS and just a while (forever loop) driven by interrupt service routines.
Currently, I use an AMTEL AVR 2560; however, I've heard good things about the TI ones.
I honestly don't know where I want to focus yet. I figured I'll continue to take some more classes to get some breadth on the subject. Once I have a better idea of what peaks my interest I'll jump into the depth for a more specialized approach when I can make a better educated decision.
Good call on Make. I've been meaning to check it out, but haven't gotten around to it.
Thank you for all the resource links. I really appreciate your response.
I'm glad that you like the info. I see that you're working on very low level stuff. Can you go even lower and deal with sensors, resistors, capacitors, opamps, and the like? These days there is a reference design in white papers somewhere so you don't need to be and expert in electronics to get away with something that works. You just need access to the tools such as multimeters and oscilloscopes.
I'm thinking sensor networks. If you can, then I would recommend to try something using the MSP430 for example, given its low power requirements. Take the microcontrollers and pair them with different sensors (eg., IR, temperature, etc) and an RF module such as xbee [9] in order to create a mesh network [10]. You'll need to work on the protocol and management side too-- a linux box somewhere with a database but that should not be a problem for you. But I realize that is more of a team project given the amount of work.
I mention this because I see some activity in this field and lately I've seen several articles, mostly in The Economist, that talk extensively on how sensor networks and the system that manage them will encroach our daily life. So if you can't figth them, might as well join them.
I'll be taking a DSP and RF class soon - so, yes, I'll be able to go lower eventually :-) My background is in CS with the bare minimum of EE. For the most part, this is all new to me.
I'll take a look at the sensor networks. Thanks again.
Sorry for taking this long to reply. Lots of errands to do.
An embedded programmer is a catch-all adjective I think. One could be working on very low level programming of microcontrollers (e.g., PIC32, MSP430) and FPGAs [11].
On the other end of the spectrum, you can find embedded programmers working on embedded devices that hosts complete systems with OS, filesystems and utilities such as the ELDK (referred in previous posts). The duties for such programmers include creating device drivers for the specific devices that the product has. I have for example, modified an existing application developed originally for a system with no OS into a Linux application running on a PowerPC board. For example, some of my duties were to modify the original application's absolute FLASH memory references to a method compatible with what the Linux based system offers (hint: I used mmap).
I would guess that someone like yourself with limited exposure to electronics would be guided toward the latter type of jobs. From my limited experience in my local area I believe that this type of jobs offers the best balance. Latter on you can move deeply into low-level development once you have beefed-up your resume if you so desire.
The trick here is to be identified by a competent manager that can match your education and experience to his needs. And you`ll be surprised how little managers need to know, technically speaking, to get a product going which means that you need to sell yourself well.
Senior positions depend heavily into the nature of the company. I find that importance given to hierarchy between employees is proportional to the amount of bureaucracy present. This translates into defined roles, which will need to be created (i.e., company is growing) or the position becomes available (i.e., because of retirement or lay-off). So for example, if you want to become an architect where you actually design a product or part of it; it will be harder in a big company. Smaller companies suffer less from hierarchy and give more chances to hold important and challenging positions but the pay usually lags far behind the bigger companies.
The best ways to get a job depend largely on the type of jobs available which are dictated by the companies implanted there. Where I am, there were several small companies that needed someone that could wear lots of hats. That`s how I started back 10 years ago. I had to manage a small network, program an 8-bit HC11 microcontroller, design the PCB, select the electronic components, do some soldering, do some mechanical design, and train the client and fix the bugs once the product was out the door. This path has led me to be a generalist rather than a specialist.
But I talked no long ago to the guy that was my boss back then, and he said that these days is cheaper to contract out the small jobs to specialized shops which wasn't the case back then or at least he wasn't aware of competent companies that offered a reasonable cost. So things do change. Be prepared to turn on a dime.
I think that you should not have too many problems going the embedded way. But you'll need to help the hiring person to match your skills to their needs. They may just assume that they need an EE just because they're working very close to the hardware. I think that you have a bright future. One of the most competent embedded programmers that I've met did a BSCS.
I hope I did not go ramble too much and loose you in the middle. Just one more thing. Remember that your worst enemy is yourself. Don't let self-doubt and/or laziness to get in the way. Control those and you'll have a good future.
Working for any primarily software driven company is going to be challenging. Working in an expensed IT department is what most developers do, and the work is pretty pedestrian. This seems to provide the most clear line of delineation in software development.
They're hard for different reasons. In my experience, games, scientific computing, trading, and 'real' web backend work (i.e. not 'move this shit into the database' but 'make the database scale to a million users') are hard because they challenge you to solve difficult problems. Web frontend and simple backend work are hard because of the pain in the ass of managing all the different languages and paradigms involved.
Yes, Web Programming can be hard, but it's probably harder than it needs to be. The whole ecosystem of HTML + CSS + JS + IE6 is a mess.
Something along the lines of Cappuccino will help a lot. Then you're "only" left with the problems of UI/UX, scaling, security, A/B testing, big data and marketing.
Until you want to do something new that Cappuccino developers didn't think of... now your ecosystem has expanded by 1 to HTML + CSS + JS + IE6 + Cappuccino :)
It's not the sort of thing we should have pride in--that web programming is hard. For me, it goes to show that web front-end programming has a long way to go to make it better for developers.
We're still looking for X to do to front end web programming that Rails did for back end web programming.
Conversely, I think traditional programming seems really hard compared to RoR. I have to think about memory? I have to tell the computer what the variable type is? What are all these funny characters and symbols? I can actually crash the computer with this? What is this compiler thing and all these funny options?
I'm (slowly) trying to re-learn C/C++ after getting decent with Ruby and honestly it just hurts. Few things I do need speed or system access on this level. The verbosity is painful, and you need so much (ugly code) to do so little.
Front-end web work, at its basic level, is not hard in the traditional "let's go shopping!" sense, but what I find maddening is how unintuitive some of it is (CSS, I'm looking at you). Then you have to worry about how broken or incompatible browsers are. I think "pain in the ass" is a more apt term.
When you get deeper into the UX, things like A/B, optimizing load time, scaling the backend, etc, and that is where it becomes less tedious and the domain knowledge required is more respectable.
It seems like there's always been a little bit of a rivalry between compiled language developers, web developers, and network administrators. Having done all three at high levels, I can say that in my experience web development (top to bottom) requires the most diversity of knowledge, which also makes it the most enjoyable to me. At any rate, I'm going to show this to my game developer buddies next time they give me crap about "working with toy languages"!
Web programming is hard but not necessarily intuitive. That's what I dislike about it. Its a heap of different technologies put together in unstructured fashion. This applies to individual technologies as well, take CSS and see how unintuitive a syntax it has.
Web programming is popular because it drives the web. I don't necessarily find it an intuitive programming experience. This way of thinking is the biggest obstacle ahead of the likes of me (hackers for pleasure) for business success, i.e. primarily focusing on what's interesting from an engineering perspective. This approach is sure to fail in business because people always care about the end result. Technology is just a tool to get there.
I guess part of the problem is when you study computer science or engineering in university, you try to learn the best engineering approaches out there and improve on your engineering skills. Then you face real life where the result matters. I cannot really say CSS or javascript is the best technology out there, but they play a crucial part driving the web.
It was funny to read this as I now find client side development ridiculously hard (I last did it frequently > 10 years ago) and difficult to get my head into, whereas even large scale Web development feels quite surmountable or even easy to me. I think it merely proves that what you keep doing, you eventually find natural.
I think the main difficulty for Web Development is the separation between the Front-End and the Back-End. In Desktop development, the two are linked together, so if you want to handle a button click, you do that in the back-end and no other hassles.
However, for Web Development, you'll need something called HTTP POST or GET and you want to improve it with AJAX (and make sure that it still works even without JavaScript). The user input become sensitive, and you have to take into account many other thing to secure your server.
Still, Web Programming is fund. Having a server that answer requests is funny, for me. The author found Web Programming is hard, because it underestimated it.
Yes, web programming is hard. The amount of techniques and the haphazard way in which they interact (jsonp??) are terrible compared to 'real' software development in a controlled environment.
But you really should be grateful for that. If it were easy a large number of us would not be earning what we do because things that are easy tend to devalue quickly.
Remember when being able to write HTML would net you $80 / hour?
Ten or fifteen years from now, when web programming is 'easy' you just might long for the times when web programming was hard but you could basically name your price if you were competent at it.
I made the jump from Objective-C/Cocoa development to web app development after Startup School this year. Two things surprised me when I really got down to coding my initial project. First, the sheer number of technologies involved in developing my web app. For me, that's Ruby on Rails, Javascript, jQuery, Ajax, HTML, CSS.
Second, the lack of integration between the various technologies was surprising. I often knew what I wanted a particular page to do, and the solution was to learn a new technology, and then figure out how to shuffle data between the new technology and those technologies I was already using.
Integration problems also crop up in the form of mismatches between technologies. For example, I use bignum integers in my code; but ran into all sorts of interesting problems: Ruby/Sqlite work fine; but as soon as I uploaded the app to Heroku, I uncovered issues with how these integers were being stored in the PostgreSQL. And Javascript needs special routines if it is going to handle bignums. I haven't encountered this sort of mismatch on the desktop.
That said, now that I've got a working app, I think the learning curve was in some ways (though not all ways) less steep than the desktop. A couple of reasons for this, I think:
1) The communities share code prolifically. It is not that there is no code sharing going on in desktop development, but code sharing seems much more prevalent in web development. As a new web developer, this makes my job a lot easier not only because I can just plug in code, but also because I can read that code and learn from it.
2) You can get minimal results quite quickly, which is very encouraging. Again, you can get minimal results quickly on the desktop, but the standards are different on the web. In my experience, a desktop app needs a lot more to be minimally functional than a web app, probably because the level of complexity is different. Yes, web apps can be just as complex as desktop apps; but I think a minimally functional web app is in many ways less complex than a minimally functional desktop app. Just think about all the menus, help files, and other accoutrements you need to get a desktop app minimally functional; web apps can get away with less.
3) The web technologies I depend on are more modern. Compared to Objective-C/Cocoa, Ruby is like a dream. Javascript and less so, but only because it seems more like what I'm used to on the desktop. What can I say, I like syntactic sugar and the readability that comes with it.
So, perhaps web programming is hard, but there are several ways travelling the path is made easier - maybe even easier than on the desktop.
I've not done any embedded stuff, but I've had jobs doing low level c/c++ to interface with poorly documented serial devices passing bit-masked instruction codes and status codes around and I'm now doing web programming and man, all I can say is this: Nothing is easy. If it looks easy for some reason, someone has probably done a lot of difficult work for you previously.
Is there a need to learn it all though?
I'm a designer at my place and here I do all the html/css work and a bit of jQuery fluff on top of that whenever it's quite basic. I do think that's how most places work.
Of course for a developer it's necessary to have some knowledge of html primarily, but no real need for deep knowledge. Not in my, somewhat limited, experience anyway.
When people complain to me about so and so technology related I tell them to relax, breath and consider the millions of things that need to go right in order for you to watch the latest Lady Gaga video on youtube.
I appreciate the author for recognizing web development. I often stumble upon my 'programming' friends who think web development and especially front-end is boring and trivial. I have hard time explaining how important and how complex things can get.
It's something my fellow hard-core programmer friends will never understand. I love my job and what I do.
There are frameworks full of very high-level abstractions that can make it a lot easier up front. BUT, that only delays it being hard down the road when the abstraction you got for free has to be replaced. Often that time comes very quickly.
Yup. I've "built a website" with Ruby On Rails but frankly wasn't too impressed with myself afterward. It was a worthwhile exercise because it got me to understand the basics of web development. I'd rather focus on learning the nitty gritty basics.
OK, if we're talking about games, maybe not. I'm talking about your average Desktop GUI out there which can be made to work across different OS's using a GUI Toolkit such as Qt.
Most of the time desktop apps and web apps serve completely different purposes. Desktop apps do not intend to be flashy or beautiful, they need to be usable for getting things done. They should follow the conventions of the OS, be fast and intuitive. So when a GUI developer creates a GUI that is highly usable and not showing off with eye candy, the GUI developer has done his job properly. Saying "they get away with it" because desktop GUIs are ugly is just wrong.
Web sites often need to draw attentation. They want to sell something, be interesting. They should be flashy and beautiful.
In my more sensible moments, I remember that that idiot only needed to know HTML, CSS, the DOM model, Javascript, jQuery, HTTP (mostly headers and status codes), Ruby, Rails, basic MVC design, Oauth, SQL, SQL performance, five-ish APIs to support the two that needed integration, how to configure and maintain a server, system architecture, a bit of security, etc.
[There's also object oriented programming, class inheritance, polymorphism, algorithms, time complexity, discrete math, data structures, imperative programming, and a few other things I forgot the first time around. Lest we forget, we might take these for granted because we've been programming since we were $ARBITRARILY_YOUNG, but to most people these are just black magic. My girlfriend, a smart cookie, asked to see "how I made the phone ring" and, after I showed her the code that did that, told me it had never even occurred to her that every program she's ever seen was once a collection of special words placed in a particular order.]
After that, it was pretty much done, except for the marketing.
On the plus side: you can learn one or a few of these things at a time, and get more comfortable with how deep the rabbit hole goes as you go along. I coded my website in static HTML written in Notepad with no JS or CSS, crikey, only four years ago. (And my brain still recoils at how much better I'd have to get to do e.g. web scale work.)