I updated from CentOS 6.3 to 6.4 today and ran into a minor issue: After performing the the 6.4 update, CentOS got stuck at the boot screen due to a conflict between the NVidia drivers I use and the nouveau drivers. From the boot screen screen, I was unable to switch [...]
I updated from CentOS 6.3 to 6.4 today and ran into a minor issue: After performing the the 6.4 update, CentOS got stuck at the boot screen due to a conflict between the NVidia drivers I use and the nouveau drivers. From the boot screen screen, I was unable to switch to a CLI unless I reboot.
Here’s how I fixed it:
At the GRUB loader, I pressed ‘a’ to edit the kernel options and added a ’1′ to boot into single-user mode. Once in single user mode, I followed just one step outlined on this site: To rename the initramfs and execute dracut:
$ mv /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak
$ dracut -v /boot/initramfs-$(uname -r).img $(uname -r)
$ reboot
Once the new initramfs was created and the system rebooted, I again interrupted the GRUB loader, pressed ‘a’ to edit the kernel options and added ’3′ to boot into multi-user mode. I logged in as root, changed to the directory where I keep my NVidia drivers and re-ran the NVidia installation tool (in my case, “./NVIDIA-Linux-x86_64-310.32.run”).
Once these steps were complete, I was able to boot into the UI without issue.
Pay no attention to the developers behind the curtain.
I’ve relayed this story many times over the years and it remains one of my favorite developer anecdotes.
As is common, the requirements of the business do not always align with the reality of software development. Occasionally, we’re asked to do something really, really [...]
Pay no attention to the developers behind the curtain.
I’ve relayed this story many times over the years and it remains one of my favorite developer anecdotes.
As is common, the requirements of the business do not always align with the reality of software development. Occasionally, we’re asked to do something really, really stupid for business to succeed. This was very much the case for the company I worked for back in the early 2000s, when I helped develop a web-based front end to a small subset of client data. I’ve touched on similar stories with this company in the past: The environment was very much the Wild West of developer environments.
The web-based front end was very new and we had spent a lot of time writing all of the various components, but it wasn’t robust and it wasn’t solid and it certainly wasn’t production-ready. In fact, it had a lot of bugs that we simply hadn’t ironed out, and we were discovering new bugs on a daily basis.
Despite our best efforts to the contrary, however, we were tasked with bringing in production client data for an upcoming demonstration with said client. The company president and VP were flying to Scotland to present our front end, bugs and all. The demonstration was already set up and we (the three-person developer team charged with the task) had adequately prepared as best we could.
However, just before the demo we discovered a problem. A big problem. The site would crash during a sort operation, and the demonstration of the sort was elemental to the demo. It’s two days before the demo and we have broken code.
We tried, desperately, to find the root of the problem to no avail. We could replicate it as long as we weren’t in the debugger: During debugging, we discovered the problem didn’t exist at all! In fact, the bug didn’t manifest inside the debugger if and only if we stopped at a specific breakpoint! Under any other circumstance, the application would fast-exit and present an ugly Internal Server Error to the client, but if we stopped at one specific breakpoint and simply continued execution, the application worked just fine!
Fun.
Our president and VP were adamant that the demo go off without a hitch. It was very important to the business. Of course.
So, we had a work around. We could execute the demo as long as we had a developer sitting at a debugger on the server, waiting for the breakpoint to hit. The developers job, then, would be to hit F5 when they saw the breakpoint. This introduced a delay, but due to the slow pipe overseas, the client (probably) wouldn’t notice.
But the demo was overseas and the developer had to be at the office at the server between 1:00 and 2:00 AM (I don’t recall the exact time, but it was late). What if the developer had to step away? Or fell asleep? Obviously the developer needed backup, and a manager present. Obviously.
So there we are, Katie the manager, Chris the developer and me as backup and we’re sitting around a CRT, all of us staring at the Visual Basic 6 IDE (yes, VB6). We get the call that the demo is about to begin and we wait for the breakpoint to hit. We had snacks. We had drinks. We were having a good time.
And we’re waiting.
We had no idea what was happening in Scotland, so we were just… sitting around. Three developers, huddled around a monitor, waiting for a breakpoint to hit.
And suddenly, there it is.
The line highlighted in yellow. We hit F5 and away it goes. And there it is again. And again. Each time, we hit F5 and each time the site functions as expected.
We get a call letting us know the demo is over, and we all return to our respective homes. For all intents and purposes, the demo was a success and the client was none the wiser.
I don’t recall, unfortunately, what we did to fix the bug. The whole component library was pretty complex, and the bug may have involved an external core dependency… but I’m just speculating. It was so long ago that I don’t remember the technical details, just the human story of sitting around a server with a couple of really great people enjoying the absurdity of the whole thing.
It’s the people I’ve learned to appreciate over the years, even if the job is occasionally stupid.
We had one job. It was stupid. But we did it. And I enjoyed every moment of it.
Have you ever had an Oz-like experience?
Begin Rant.
I spent the last week-and-a-half with my father, a very bright man who doesn’t really get technology and doesn’t necessarily want to get technology. Case in point: Over the holidays my father proudly presented – to everyone in the room – his handwritten list of usernames and passwords which he “secures” under the [...]
Begin Rant.
I spent the last week-and-a-half with my father, a very bright man who doesn’t really get technology and doesn’t necessarily want to get technology. Case in point: Over the holidays my father proudly presented – to everyone in the room – his handwritten list of usernames and passwords which he “secures” under the lid of his laptop.
Yikes!
This got me thinking about security. I don’t blame my dad for completely misunderstanding computer and web site security: It’s all very complicated. He’s never been trained in security matters, which is largely my fault since I’m the person most knowledgeable in my family of such considerations. In fact, my entire family simply doesn’t care about computer security. All they want to do is pay bills or stay in contact with friends: They’re not actively participating in the culture of technology. To stop their workflow to consider security matters is simply asking too much.
People like my father simply don’t understand enough to care. And here’s the rub: It’s my fault he even needs to care or understand. It’s my fault because – as a technology enthusiast and software developer – I have not made security the simple default! I could train my father, but that’s only a small part of a much bigger problem.
Security adds complication because it’s not simple. Usernames add complication. Passwords add complication. Remembering multiple usernames and passwords for multiple computers or web sites is almost impossible for a lot of people. Security breaks the common pattern of use.
My laptop and desktop are encrypted. I use two-factor authentication schemes wherever I can, and my passwords are easy to remember but difficult to crack. I employ a password manager for some things, but not all. I like to believe that my online identity and the data I really care about are all very well protected.
However, I’ve also spent the better part of my life working with computers. I innately understand how the hardware and software work, and I understand and deeply care about security. Encrypting my drives is just something I do as a natural part of configuring a new computer. Security is a habit. How do I even begin to explain, then, the purpose behind such a concept – let alone the actual steps required to perform such a process – to someone who simply isn’t interested, or finds the whole process too complicated to undertake?
In many ways, I shouldn’t need to. Security should be the simple default.
As an example, I recently purchased a Google Nexus 10. When I opened the box and turned it on, Android immediately asked me for credentials. This is good. Sort of. By default, however, it didn’t encrypt the device. This is bad. Why didn’t it? It could have. It should have. And it could have performed such encryption on the live file system without interrupting user workflow. I know of a couple of encryption applications that do just that. Instead, Android blocked access to the device for the few hours it required to encrypt. No novice computer user is going to wait for – or understand the purpose behind – such a lockout. It interrupts their workflow and it makes data security an unnecessary complication by default.
It should be the other way around!
Yes, I understand that novice users can (and do) forget their passwords, which would render an encrypted device useless, but I see forgetfulness as a separate issue.
I said it was “sort of” good that Android asked for my credentials. Sort of. It was great that it asked for credentials, but the experience was terrible. I signed up for Google’s two-factor authentication scheme. Android doesn’t natively support Google’s two-factor authentication scheme. Oops. Once I entered my username and password, Android broke the workflow and opened up a web browser to request my authentication token. It’s all neat and great that it worked, but what a pain in the ass! Even for me: And that’s the way I intentionally configured my account and I expected it! How’s a novice user going to understand such nonsense?
It wasn’t simple and it wasn’t the default.
Indeed, it’s our fault – the developers fault – that the state of security is such a disaster: We don’t make it easy because it’s an incredibly complex problem to solve. Security isn’t the default for anything but it should be the default for everything. Because it’s not the default, it breaks the common pattern of use when we have to stop and think about it!
It supposedly took Facebook two years to roll out the infrastructure required to support HTTPS for its 1 billion users. Two years without HTTPS! Prior to that, you had to opt-in for SSL. That’s not simple and it’s not the default! Yes, I appreciate the architectural concerns faced by Facebook. However, my family shouldn’t have to think about this kind of crap and neither should yours. Oh, and let’s not discuss security authentication abuse by such companies, either. This type of behavior is just spitting in the face of user data protection.
It’s not all doom and gloom, though. It’s getting better. We have better ways to authenticate that nobody outside of technology circles really appreciates. This will slowly change. Even so, for the technically literate, two-factor authentication is troublesome to use. It needs to get better. It needs to be streamlined. It needs to be the default, not some opt-in feature.
We can certainly do better from a developer perspective. We need to consider how we can make security considerations as simple and elegant as possible. Encryption and authentication should not be secondary considerations. We must make it simple. We must make security the default option, not an opt-in.
We can find opportunities to educate those who don’t care or understand. We should help them care. We should help them understand. I had the perfect opportunity to educate my father about sites like LastPass and I let it slip through my fingers. He may never use such a service, and he’ll probably never hear the terms “two-factor authentication” outside of me, but as someone passionate about technology, it’s my responsibility to ensure he’s been appropriately educated.
As an industry, too, we need to make it simple. We need to make it the default option on all services we provide.
End Rant.
I’m good at some things. I’m bad at some things.
I was looking through the *nix spellbook and – quite by accident – stumbled across the Programmer Competency Matrix. Again. I’ve seen it before on Hacker News (here, here, here,
I’m good at some things. I’m bad at some things.
I was looking through the *nix spellbook and – quite by accident – stumbled across the Programmer Competency Matrix. Again. I’ve seen it before on Hacker News (here, here, here, here, here and here, too), but today I actually took the time to read through the matrix and mentally quantify my abilities.
Because I like applying arbitrary opinions to my skill set and abilities.
Objectively, of course.
For a developer not formally educated in Computer Science, I did pretty okay. This comes largely, I suspect, from my dedication to constant learning and my passion for technology. And it’s not that this matrix identifies every single strength or weakness of a developer, but it’s an interesting identification mechanism nonetheless.
Recognizing where we’re weak will help us identify areas for improvement.
For example, according to the matrix my weakest area centers around algorithms. As an illustration, I understand the concepts behind Dynamic Programming, but I don’t yet possess the education to formalize the method. A degree is most assuredly in my future, and I’m excited to learn the math behind the science (among other things).
Early on, I wanted to dive right in to the experience of my chosen profession, gaining education while I worked. Dedicating myself to learning various technologies has always been an important aspect of my personality, but the decision to forego education for experience had far-reaching consequences. It was the right decision for me at the time, but I don’t necessarily recommend this path to everyone.
As John Sonmez notes, the more we know, the less we know. I could have used this wisdom fifteen years ago!
Indeed, after working in the industry for close to fifteen years and looking back on what I knew, what I thought I knew and what I learned I didn’t know, I can unabashedly state that – to be a truly competent programmer – a formal education isn’t strictly necessary, but it would be really, really helpful.
So here’s my wisdom: Irrespective of everything else, the one class I’d recommend every new developer take early in their career would be an Introduction to Algorithms course. Maybe even compiler theory. Even before looking at the matrix, I could have identified algorithms as the single biggest source of my programming weakness. Practical application of algorithms in my every day career has solidified my ability to use the appropriate algorithm for a given task, but it came at the cost: I had to work harder, not smarter in some cases. I had to read more books, more web pages than I may have needed otherwise.
Basically, I had to learn the hard way!
So don’t do it my way. Don’t learn the hard way. Education and experience go hand in hand, but make sure you do it in the right order.
And never be afraid to go back and learn!
Some people have 10 years of experience. Others have 1 year of experience 10 times.
Have you a valediction, boyo?
– James Cromwell as Captain Dudley Smith, L.A. Confidential, 1997
I recently had the most interesting chat about documentation on the way to the local coffee shop.
My department has been having a lot of discussion around documentation. We’ve been working through software design specifications, functional design specifications, business [...]
Have you a valediction, boyo?
I recently had the most interesting chat about documentation on the way to the local coffee shop.
My department has been having a lot of discussion around documentation. We’ve been working through software design specifications, functional design specifications, business requirements documentation… all for a single release for a single project, and we have many releases and many projects. It’s a lot of writing and a lot of work and it takes a lot of time. Apart from the specifications, we also have process documentation, corporate mandates and email and wikis and SharePoints and intranets and thousands of Word documents scattered all over the network, not to mention all of the undocumented tribal knowledge that’s scattered throughout the entire organization.
It’s really kind of a mess.
We were talking about documentation in general, and one of the developers mentioned that the functional design specification needed to be updated every sprint in order to give QA the required documentation for testing, but that the time required for updating documentation was far too excessive, that too many details were being captured.
That it wasn’t sustainable. The developers were concerned (and rightly so) that documentation would stagnate as code matured. What good is stagnant documentation? Outdated specifications are rarely useful, or are only useful for their historical insight.
The whole conversation sent up a red flag. We should be generating our documentation, not writing our documentation! The only valid documentation is the code itself!
The fact that we were so concerned about the creation, publication and maintenance of functional specifications indicated a fundamental flaw with the importance we were placing on certain aspects of the SDLC. Yes, we need documentation. No, we don’t need to be writing documentation by hand for every release. Why? It’s impossible to keep hand-written documentation in sync with an amorphous project, just like it’s impossible to code within a team without revision control. Fine, not impossible, but it’s extremely prone to error.
The actual code is the only meaningful documentation in the entire project. TrackAbout had it right: A backlog involved an initial breakdown period which – more often than not – required the developer to read some code! We occasionally referenced a wiki, or interrogated a team member for tribal knowledge… but ultimately, the code itself documented the process.
I’ve already mentioned that I consider the ability to read code one of the most important qualities of a developer. In an agile environment, QA members and developers should be engaged the moment a backlog enters some workable state. Developers should read the actual code – the only documentation that matters – and communicate changes to the QA team.
Ever notice that code comments within a project drift from the actual code they’re commenting? I’ve met very few developers with the discipline to immediately reflect code changes in comments. That being the case, how is your organization ever going to keep a completely separate document like a functional design specification up-to-date with such a fast moving target?
It’s simply not possible. I’ll say it once more: The only meaningful documentation is the code itself. Find ways to automate the generation of your documentation, and consider your codebase the absolute central authority of your codified business processes.
Latest Posts
- GeForce GTX 660Ti, NVidia, Nouveau and Updating from CentOS 6.3 to 6.4 (2013/03/10)
- One time, at work… (2013/01/17)
- My Family Doesn’t Care About Security (2013/01/09)
- Programmer Competency Matrix – Education and Experience (2012/12/21)
- Your Code Is The Only Meaningful Project Documentation (2012/12/19)
- I’m Not Arguing With You Over Your Terms of Service (2012/12/18)
- Embracing Change (2012/12/18)
- Finding Quality Developers is No Easy Task (2012/12/14)
- From Avid Gamer to Architect (2012/12/10)
- It’s Bugs All The Way Down (2012/12/07)
- wordptr.libwpd – Expanding Configuration, Changing the Interface (2012/12/07)
- On Tightening Focus (2012/12/06)
- 20 Days With the Google Nexus 10 (2012/12/05)
- wordptr.libwpd – Hooking the Main Loop (2012/12/04)
- I Didn’t Read The Docs – MDADM and Hostname (2012/12/02)
- My Developer Toolbox (2012/12/01)
- wordptr.libwpd – Making it More Library-Like (2012/11/30)
- wordptr.libwpd – Now a Static Library (2012/11/29)
- A Linux Daemon Library – Introducing wordptr.libwpd (2012/11/28)
- CentOS, VMware Workstation, Development and Piece of Mind (2012/11/27)

