The demise of the low level Programmer.
altdevblogaday.com
altdevblogaday.com
But...all abstractions in computing are leaky, and not having an understanding of lower levels of abstraction will come back to bite you.
The simplest example is floating point: how many pennies have been mis-appropriated because a developer used a float instead of a fixed-decimal number. If you understand how the underlying floating point abstraction leaks, you would never use an IEEE float for anything requiring exact decimal values; if not, you feel comfortable using the native type that has the ability to represent decimal values. You don't need to actually know how the float is represented to achieve that.
The real trick is understand how much of each layer of abstraction you need to know. A generalist needs to know enough about computer architecure, the network stack, security, etc., that he knows when he either needs to consult an expert (Google often counts ;) or when he is ok to rely on that abstraction, but if you try to learn too much, well, you aren't a generalist anymore.
Great generalists are, by definition, great at figuring that out. As a result, they are incredibly valuable because they are really good at just getting stuff done.
However, that doesn't mean that people aren't learning it anymore. They're just starting with a broad set of high-level knowledge and drilling down into the parts that are important to them. For instance, recently I've been toying with compact string representations of big integers (using bit shifting: how topical).
The end result is that you end up with developers who have broad knowledge of the higher layers of abstraction but incomplete and specialized knowledge of the lower layers. That seems perfect to me.
.. yet it is sad when a freshly minted CS grad thinks bit shifting and multiplication have nothing in common.
I don't lose much sleep at night worrying about my job security as a "systems" programmer. If anything, my skill set is becoming underrepresented and hard to staff.
That makes them harder to find, but there still there. Wouldn't be surprised to find out there are actually more of them than there were 20 years back.
The border of where "low level" begins is also shifting. I, for one, am glad I no longer have to hand assemble my own multiplication code :-)
I've come across many situations where saving a few extra bytes of RAM here and there and saving a few instructions during an interrupt routine have been vital.
http://www.chrisstucchio.com/blog/2011/mapwritable_sometimes...
EDIT: Honest question... didn't mean to come off wrong there. :(
Plus some of the more dated chapter can be seen as a good history lesson :-)
http://www.gamedev.net/page/resources/_/technical/graphics-p...
Also, the man's a fucking beast: http://www.mobygames.com/developer/sheet/view/developerId,21...
I mean, we live in a world where we have programming languages that COMPILE TO JAVASCRIPT.
That said, I applaud this guy's OCD fascination with low level optimization. It's only because of people like him that higher level programmers can even exist.
It's important to be able to work nominally at the N'th level of abstraction but be able to jump to level N - 1 if need be. Computer systems are full of leaky abstractions, and if you work long enough they will probably impact you at some point.
When was the last time an Excel macro developer needed to know semiconductor physics in order to debug a fault lying in the silicon layer?
When has a Ruby on Rails programmer ever needed to know quantum electrodynamics to track down a hard disk error?
Abstractly you may consider that knowledge to be useful, but concretely, there's a reason people specialize - each of those domains takes years to gain competence, and there's a good probabilistic argument against everyone being "able to jump to level N - 1" all the way down.
Most people can't "jump" to a level lower than they are used to working. They have some idea of the overall concepts, yes, but it takes time to get up to speed. Most Java people have some ideas of how the JVM works, but few can jump to (say) the JVM's memory allocator code (even when available) in order to fix problems.
In any case, does a Java programmer need to know chip layout design in order to program, or do you agree that that is "some layer below which is unnecessary to understand"? Yes, someone, somewhere, might have had a problem in Java code caused by noise leaking across from one circuit to another, but you can't seriously expect that most people will be able to jump there if needed.
I can remember starting to program our brand new PET-2001 in BASIC (at 13 years old or so). After a while I became bored with the sluggishness of BASIC, and the cramped memory space. Only very small BASIC programs would fit. But there was a new challenge! I wanted to discover what made the PET really tick -- how did it understand BASIC? Then I learnt about ROMs, RAMs and the 6502 CPU, and how to program it in machine language. It was similar to programming programmable calculators, which I'd done since I was 9. But the 6502 worked much more faster, and had a rich instruction set, compared to those old calculators; and a much better screen, with graphics!
Since I was a kid, I always wanted to look into the inside of toys how they worked, for example, my 'Brummkreisel'[1] spintop. At 6, I wanted to open my hamster to look inside, but my mother wouldn't allow it... (Otherwise maybe I'd be a surgeon nowadays ;-)
[1] http://en.wikipedia.org/wiki/File:Brummkreisel_BW_2011-08-12...
It looks like book from the course, which covers all of that material, is pretty widely used, too: http://csapp.cs.cmu.edu/public/adoptions.html
However, my first job out of college was doing low-level optimization at a cellular silicon provider, but now I work on the web since it seems like most hardware companies are bigger and have more suburban locations (neither of which is my preference), and if you're working hardware you can't work remotely. Hardware companies also aren't necessarily the best software organizations.
I like that he provides some links for further reading, and I'll bookmark the page for that reason alone.
Besides those links, his diatribe seems to be misplaced. For many applications, it's not necessary to know the difference between floating and fixed-point.
Perhaps one day, it will no longer be necessary to care about the difference between decimal/integer/floating-point, as the compiler/interpreter will know how and when to use the "right" one. And I will welcome this. I've seen inexperienced developers use float(val) when counting money; and no amount of training will stop the next generation of new programmers making the same mistakes.
The hardest part would be getting those sane defaults, otherwise everyone will override them anyway, and you're back to square one or worse.
Clojure has with-precision [1] and Common Lisp has defaulted to fixed point, fractions and explicit ^float type annotations.
[1] http://clojuredocs.org/clojure_core/clojure.core/with-precis...
Sounds like a big success, then!
Isn't this what every high level programming language designer aimed for?
I remember the days of writing GEM apps in 68k assembly...
And from time to time there comes another layer on top of everything else, and you wish you could forget the lowest layer you know, just to not start going insane. Or at least to slow it a bit :)
Can you toggle in a new A/D converter? Can you toggle in a connection from your screen refresh to a CPU interrupt? Can you toggle in a switched memory bank so your hardware can handle more memory than the CPU was designed for? Obviously not.
These are the things you lost if you 'jump straight into writing "software" in asm or C or whatever.'
Software is solving much more difficult problems than ever before thanks to this evolution to higher abstractions.
Case in point: I once had a co-worker show me a Java crash report from a crash that nobody could figure out. Every now and again, the server, Tomcat, JVM and all, would just die, spitting out a stack trace that went into native land.
One really nice thing on the crash report was a full register dump, stack address dump, and a dump of the memory around the PC. So I disassembled the memory, figured out that it was calling memcpy when it died, and lo-and-behold, one of the register operands was 0! A comparison of the stack addresses showed that it was dying in a library used for biometric fingerprint based authentication.
The vendor kept insisting that the problem was on our side (we had a JNI library of our own that called their library, but I desk checked it twice and concluded that it was fine), so I disassembled the whole library and traced what it was doing. It turns out that certain kinds of incomplete fingerprint scans wouldn't trigger a rejection at the high level, but would cause a rejection at the lower levels (almost... it would clear the pointer to the data but would then return TRUE instead of FALSE). The library would then carry on its merry way passing a null pointer lower and lower until it died in memcpy, taking the JVM with it.
Please prove that. :-)
Most of what I see is reskinned GUIs from the early 80s... first on Mac OS, then on Windows, then on OSX, then on Linux, then on the Web, then on handsets...
more pixels per inch != more essentially complex.
big data was being handled by bank mainframes in the 1970s (the original cloud computing. :o).
The list goes on and on and on. I can't imagine how anyone could seriously argue that we're not leagues ahead of where we were in the 70s.
I used to play Elite too and, while it had some unique qualities, it wouldn't compete with any of the better modern titles for my attention now.
RPi claims it will get kids interested in programming again, but in the end it's just a supercheap Linux box. I think you'll see more kids want to make their spaceship do something really cool and really efficiently on the virtual in-game CPU. The instruction set is small and tight and very easy to learn. I know everyone wants to build compilers for every language under the sun for DCPU, but just like in game programming the tighest code will win.
Just throwing that idea out there.
Something simpler and cheaper than Mindstorms, yet more open and easier to experiment with.
10 PRINT HELLO is slightly more obscure on a Linux desktop. This is where I see RPi falling down in the educational market and it turning into another hobbyist breadboard.
I credit this exposure to 8-bit low-level programming at a young age for my easy experience in computer architecture and operating systems classes later on.
He's screwed, near as I can tell, unless he can find at least half a year to sit down and learn C / C++.
If he's a good programmer he shouldn't give up. If he's job hunting, tell him to spend a good two weeks learning C++ and build a couple of dummy programs, then start applying for roles and continue to work on his C++ in the background. It'll come.
Though let me say that this is where I think good universities play a crucial role. A lot of my class mates had never written a line of assembler or C before university, and by the third year we had all built CPU's, compilers, operating systems and a few robots. Some of that is bound to stick and help you grow an intuition about the towering stack of complexity below the browser window.
I think low level jobs need more visibility. Perhaps a monthly "Who's Hiring" thread for low-level jobs would help.
Many employers (specifically Intel, but I've seen many others) specify an ABET-accredited BS program in education requirements for job openings.
(Full disclosure: I worked at ND).
But systems programming seems to be an essential role that uptime-concerned operations will always want on retainer...
For instance working on web apps, when you an extra server costs $400/month (4 developer hours or less), what value is there in spending days hand-optimizing an algorithm (into a form that'll be harder to debug later)?
Another example: writing mobile apps. On a phone today you have 1 GHz of power, but still a very limited interaction model. It seems basically only games actually need to optimize for performance.
Reducing latency?
Throwing servers at a latency problem doesn't usually help (unless a server is overloaded).
So I'm asking : career-wise, are the optimization ghettos (video games, embedded systems, critical systems etc.) all that one could expected when refusing to code and manage projects around buzz-words or is there actual innovation / change and a shiny future to come for bit nerds ?
That said, my day to day life lives more in the realm of scripting/interpreted languages and occasionally diving into C/C++. Even in C++, though, frameworks like Boost make C++ seem higher level than it is.
Today, we see a need for people that can work on Cobol and companies providing Cobol=>Java bridges. I suspect the need for the lower level programmer may occupy a similar nitch in a few years...
Even assembly code appears high level when you are looking into how the electrons run through silicon and copper. But it's not realistic to cover all the stack down to the atoms. Then which layer you can stop digging at?
For a programmer, the processor architecture (including the instruction set architecture and the bus architecture) level would be fine. It is the strongest abstraction barrier and you rarely need to look below it.
That said, if you are working on embedded systems, knowledge about digital electronics is almost a must, and some analog bits really helps.
In the console world the author is leaving in, hardware iterations are usually slow. As an example take Tekken 2 vs. Tekken 3 and notice the difference in the graphics. Same hardware (PSX), better software.
2) My (soon to be former) work is in signal processing software for military applications. Our customers do not want to buy and upgrade hardware just because some new algorithms don't fit. This creates a situation like the console world (as klez mentioned in his reply) and the mobile device world, where hardware is basically fixed for some period of time for a given user. You have to pay attention to the efficiency of code in these circumstances if you want to expand the capabilities of your applications in any meaningful way.
C++ is making a big comeback where instructions/joule matters
- andy firth (the author)
There is more embedded code and applications out there than ever before, and tons of mobile devices that need similarly low level code.
Low-level programmers have been dying ever since the first assembler was invented.
Up and coming low-level programmers still exist. I just turned 20 this past January and I've been doing x86 at least once a week for 5 years now, in fact, my meal ticket -- IDA Pro, sits as I type this whirring away at calculating the relocations of some PIC in our favorite browser.
While it may be true that that the majority of people with assembly knowledge are slaving on heap sprays more than swizzling pointers or tackling alignment issues these days (or any other "real" low level work). All and all, auditing isn't half bad and I suppose the markets agree.
I guess to that end, There's going to be no shortage of low level junkies as long as kids still think hackers are cool. Kids are going to be attracted to the cyberpunk glam of hackers (or, naturally, Angelina Jolie's smoking body in 1995). Of course, as it goes, If you want to be any good at that sort of thing, you have to write memory corruption bugs, and if you're writing memory corruption bugs then low level is a necessity.
So while it may be true that producing anything save VX crypters in assembly is a dead end, the deep knowledge is immensely rewarding and while it's true you might not be able to erect castles, you can perform some deep machine magicks that will make a few people's heads turn.
You unlock many things that many programmers simply dream of -- The ability to reverse applications, to tweak some 'interesting', decidedly-nonoptimal optimizations (LEA is always faster!) and find cleverly exploitable bugs in applications that you don't have to source to.
You can optimize in ways that other programmers, no matter how skilled in any other language, simply cannot. A recent and related anecdote is my database ( zv.github.com/artifact ) which, once upon a time, was extremely slow during the mkey exchange when it diffs the hashes against it's own, it was copying every hash and comparing it to every other hash it had received thus far (For when quadratic time is too fast). Normally this would have been a few hours long job to rewrite some pithy external library, write tests and somehow implement speedy string manipulation in Erlang. Nope, HiPE allows you to treat an object file as a module as long as it has the correct export interface. My humble database is now an order of magnitude faster on convergence (This may speak more towards the performance of string processing in Erlang than any personal prowess, but still).
So, in conclusion Mr. Andy Firth, it's probably true that the vast majority of people who you are interviewing aren't very good, because hey, that's the central limit theorem at work!
However, I assure you, somewhere out there, there's a boy and his linker, learning low level the hard way. If I were you, I'd hit up security and reversing/crackme forums, you're practically guaranteed to find a wizard or two.
That's the Circle of life :)
I took a class last semester where we had to write an assembler and virtual machine for MIPS (in C), had exams on branch prediction, instruction pipelining, program-performance as impacted by different types of caches.
But really, there is a lot of information to absorb. Intel's been doing heavy research on processors for decades. It's one thing to be familiar with the concept of branch prediction and instruction pipelining, it's another thing to know enough to actually have a [positive] impact on the performance of a program.