Twenty five years ago, when Steve W. worked for a military subcontractor, he'd often roll his eyes when meetings were denoted "CONFIDENTIAL". It's not that he didn't take confidentiality seriously, it's just that everything they did was confidential. By labeling most everything "CONFIDENTIAL", there was no way of knowing when some things – like performance reviews and should-we-fire-so-and-so discussions – were really, really confidential. At least, not until you were actually in the meeting.
At one meeting, it was was really, really confidential. It was a one-on-one and across the table from Steve sat the Project Manager. These kind of solitary meetings took place either because you're doing something very wrong... or you're getting canned.
"Hey Steve," the project manager started, "I need a fresh set of eyes on a performance problem we've been facing with the EC Unit."
Steve perked up at this. And not just because he wasn't getting fired, but because the EC Unit — EC being short for Electrical Capabilities — was a pretty big deal as of late. It was a "switch" on one of their new automated testing stations with hundreds of relays configurable to variety of electrical ratings: 50 Milliamps at 0.01 Volts, 400 Volts at 200 Amps, you name it. Being about the size of a VW Bug and having a panel of blinking indicator lights which actually meant something, it was an impressive sight... and had an equally impressive budget to boot.
The project manager continued, "it's taking in the neighborhood of eight hours to run through an engineer test script and that is really hurting us on turnaround. If you can crack this nut, you just might be the hero of the project."
A HERO'S WORKEagerly, Steve got to work on familiarizing himself with the EC's software. Basically, the idea behind the program was that, as part of a test, the engineer would write a statement like "Apply X amps at Y volts to circuit C with waveform..." and the program would compute the least electrically expensive path.
Developed by the primary contractor, the code weighed in at about 5,000 lines of Pascal and, with a myriad of functions and high math, it was certainaly no picnic. For days, he poured through the logic. After single stepping though the program and creating enough flow charts and flow diagrams to cover two walls, nothing jumped out at him. However, when Steve added a global counter in every function in the application (as there was no profiler available), he hit paydirt.
While most functions were called proportionally to the number of connections to be analyzed, the following worst offending function was called over a billion times.
function eval_strings_are_equal(s1:string[255], s2:string[255]):Integer «reasonably efficient string compare function implementation here» endThe funny thing about that innocent looking function was how the program handled the parameters. Can you see it? No matter what the size of the string data — even as few as two characters — the program would copy two 255 byte sequences to the stack, one byte at a time. Steve found that if he changed the parameter declaration to the *even* number 256, the parameters would be copied to the stack *two* bytes at a time and reduced the runtime by half!
But, was 256 bytes...overkill? Steve looked further and found that the longest strings ever passed would only be 8 bytes long - he reduced the parameter length to match. The end result: an analysis that would ordinarily take an entire business day would be done in a half hour.
No doubt about it - Steve was the man. And better yet, it wasn't even his company's fault: the primary contractor was responsible for that particular module.
AFTERMATHAt their next "CONFIDENTIAL" meeting, the Project Manager started without a word of small talk. "So do you have something for me?"
Steve smirked and nodded, with a smug Yeah, you better believe I do! and handed over the documentation with a very nice "before and after" graph on the first page.
"WOW!" the project manager was shocked, "This is good!...REALLY GOOD!"
Before Steve could even explain how he did it, the project manager jumped in again. "However," he said slowly, "we're going to have to sit on this for now. We can't tell them about this."
Steve shot back a quizzical look as the project manager explained. As it turned out, there was a big political fight going on with the primary contractor about the project. The primary was blaming Steve's company for overall Electrical Capabilities slowness and Steve's company was blaming the hardware supplied by the primary. Not that it really mattered, because there was a planned upgrade to the Electrical Capabilities system that, among other things, promised much higher performance.
"It's only a single line code change," Steve implored, "it would take all of five seconds to explain. Then the users would be up and run-"
"Yeah, yeah," he brushed off, "we'll keep it as our 'ace in the hole' in case they complain about slowness after the upgrade. We'll show 'em that we're not the ones who are causing all the problems."
"But isn't the upgrade several months away?" Steve rhetorically asked, "we can get them to implement it now and save thousands of client man hours in the mean time."
The project manager glared, "you're not going to share the patch information. It's confidential."
As the planned upgrade date came closer and closer, the likelihood of actually upgrading seemed less and less likely. When the date had come and gone, the upgrade project was "put on hold until next quarter". And it stayed on hold for quarter after quarter after quarter.
Five years later, when it came time for budget cuts, the entire Electrical Capabilities project — military personnel and all — was cut for good. Apparently, the auditors weren't too thrilled that engineers just sat around all day, waiting for some program to run.
Twenty five years ago, when Steve W. worked for a military subcontractor, he'd often roll his eyes when meetings were denoted "CONFIDENTIAL". It's not that he didn't take confidentiality seriously, it's just that everything they did was confidential. By labeling most everything "CONFIDENTIAL", there was no way of knowing when some things – like performance reviews and should-we-fire-so-and-so discussions – were really, really confidential. At least, not until you were actually in the meeting.
At one meeting, it was was really, really confidential. It was a one-on-one and across the table from Steve sat the Project Manager. These kind of solitary meetings took place either because you're doing something very wrong... or you're getting canned.
"Hey Steve," the project manager started, "I need a fresh set of eyes on a performance problem we've been facing with the EC Unit."
Steve perked up at this. And not just because he wasn't getting fired, but because the EC Unit — EC being short for Electrical Capabilities — was a pretty big deal as of late. It was a "switch" on one of their new automated testing stations with hundreds of relays configurable to variety of electrical ratings: 50 Milliamps at 0.01 Volts, 400 Volts at 200 Amps, you name it. Being about the size of a VW Bug and having a panel of blinking indicator lights which actually meant something, it was an impressive sight... and had an equally impressive budget to boot.
The project manager continued, "it's taking in the neighborhood of eight hours to run through an engineer test script and that is really hurting us on turnaround. If you can crack this nut, you just might be the hero of the project."
A HERO'S WORKEagerly, Steve got to work on familiarizing himself with the EC's software. Basically, the idea behind the program was that, as part of a test, the engineer would write a statement like "Apply X amps at Y volts to circuit C with waveform..." and the program would compute the least electrically expensive path.
Developed by the primary contractor, the code weighed in at about 5,000 lines of Pascal and, with a myriad of functions and high math, it was certainaly no picnic. For days, he poured through the logic. After single stepping though the program and creating enough flow charts and flow diagrams to cover two walls, nothing jumped out at him. However, when Steve added a global counter in every function in the application (as there was no profiler available), he hit paydirt.
While most functions were called proportionally to the number of connections to be analyzed, the following worst offending function was called over a billion times.
function eval_strings_are_equal(s1:string[255], s2:string[255]):Integer «reasonably efficient string compare function implementation here» endThe funny thing about that innocent looking function was how the program handled the parameters. Can you see it? No matter what the size of the string data — even as few as two characters — the program would copy two 255 byte sequences to the stack, one byte at a time. Steve found that if he changed the parameter declaration to the *even* number 256, the parameters would be copied to the stack *two* bytes at a time and reduced the runtime by half!
But, was 256 bytes...overkill? Steve looked further and found that the longest strings ever passed would only be 8 bytes long - he reduced the parameter length to match. The end result: an analysis that would ordinarily take an entire business day would be done in a half hour.
No doubt about it - Steve was the man. And better yet, it wasn't even his company's fault: the primary contractor was responsible for that particular module.
AFTERMATHAt their next "CONFIDENTIAL" meeting, the Project Manager started without a word of small talk. "So do you have something for me?"
Steve smirked and nodded, with a smug Yeah, you better believe I do! and handed over the documentation with a very nice "before and after" graph on the first page.
"WOW!" the project manager was shocked, "This is good!...REALLY GOOD!"
Before Steve could even explain how he did it, the project manager jumped in again. "However," he said slowly, "we're going to have to sit on this for now. We can't tell them about this."
Steve shot back a quizzical look as the project manager explained. As it turned out, there was a big political fight going on with the primary contractor about the project. The primary was blaming Steve's company for overall Electrical Capabilities slowness and Steve's company was blaming the hardware supplied by the primary. Not that it really mattered, because there was a planned upgrade to the Electrical Capabilities system that, among other things, promised much higher performance.
"It's only a single line code change," Steve implored, "it would take all of five seconds to explain. Then the users would be up and run-"
"Yeah, yeah," he brushed off, "we'll keep it as our 'ace in the hole' in case they complain about slowness after the upgrade. We'll show 'em that we're not the ones who are causing all the problems."
"But isn't the upgrade several months away?" Steve rhetorically asked, "we can get them to implement it now and save thousands of client man hours in the mean time."
The project manager glared, "you're not going to share the patch information. It's confidential."
As the planned upgrade date came closer and closer, the likelihood of actually upgrading seemed less and less likely. When the date had come and gone, the upgrade project was "put on hold until next quarter". And it stayed on hold for quarter after quarter after quarter.
Five years later, when it came time for budget cuts, the entire Electrical Capabilities project — military personnel and all — was cut for good. Apparently, the auditors weren't too thrilled that engineers just sat around all day, waiting for some program to run.
As a postgrad in the late '80s, Neil Bowers made some extra book money by acting as a helper in the computing lab. At the time, undergrads were all working on a grindingly slow VAX-11/780, and Neil and his fellow postgrads were posted there for hands-on help. This tended to be focused at the start of the year, when there were groups discovering Unix and programming for the first time.
One time, an Irish girl asked Neil for some help, saying that she couldn’t understand what was going on: she thought her program looked right, but for some reason, each time she ran it she got partial output, and varying amounts of output each time. The homework assignment she was working on involved writing a program that generated various values and wrote the results in ascii tabular form to a file.
Neil went over to her workstation and had a look at her source code. Everything looked fine. She showed him the file generated by her last run, and indeed, it looked truncated. Hmmm. "Ok," Neil asked, "can you run your program for me, so I can see what happens?".
She typed ./a.out and hit return. Her left hand darted to the keyboard and she hit Control-C. Neil was still mentally processing this when she cat'd the output, and turned to say, "See!" It did indeed contain partial output. Again.
"Um," he paused, "can you just run it again please?" Neil figured that he must have not seen right. But once again she typed ./a.out, hit return, then whap! she hit Control-C. Neil asked her why she hit Control-C every time she ran her program.
"Well," she said confidently, "I discovered that Control-C makes the % prompt come up quicker!"
As a postgrad in the late '80s, Neil Bowers made some extra book money by acting as a helper in the computing lab. At the time, undergrads were all working on a grindingly slow VAX-11/780, and Neil and his fellow postgrads were posted there for hands-on help. This tended to be focused at the start of the year, when there were groups discovering Unix and programming for the first time.
One time, an Irish girl asked Neil for some help, saying that she couldn’t understand what was going on: she thought her program looked right, but for some reason, each time she ran it she got partial output, and varying amounts of output each time. The homework assignment she was working on involved writing a program that generated various values and wrote the results in ascii tabular form to a file.
Neil went over to her workstation and had a look at her source code. Everything looked fine. She showed him the file generated by her last run, and indeed, it looked truncated. Hmmm. "Ok," Neil asked, "can you run your program for me, so I can see what happens?".
She typed ./a.out and hit return. Her left hand darted to the keyboard and she hit Control-C. Neil was still mentally processing this when she cat'd the output, and turned to say, "See!" It did indeed contain partial output. Again.
"Um," he paused, "can you just run it again please?" Neil figured that he must have not seen right. But once again she typed ./a.out, hit return, then whap! she hit Control-C. Neil asked her why she hit Control-C every time she ran her program.
"Well," she said confidently, "I discovered that Control-C makes the % prompt come up quicker!"
It was the early 1990s and Frank was living the dream – unshaven, in pajama bottoms and his favorite hockey jersey, having just woken up at 12:18 PM, was now working in the dim light of his basement on one of his freelance projects. Just as he was sipping a cup of coffee, the phone rang.
Frank tried fruitlessly to fight an unexpected open-mouthed yawn when he picked up the receiver. "OOOOAAAaaahhhh... hello?"
"Hi, Frank. We have a very exciting opportunity for a qualified individual like you. Interested?" Odd that this caller hadn't even identified what company he was with, Frank thought. After sleepily getting some of the details, yeah, Frank was mildly interested, and he agreed to an interview in 30 minutes... at a bagel shop that was 25 minutes away.
Ten minutes late and having not changed at all aside from putting on non-pajama pants and shoes, he was immediately flagged over by a man in a nice suit. "You have the look like a computer genius, I already know you're perfect for this," he said without a hint of sarcasm. He asked lots of vague questions about computers; stuff like "So you know computers? What about, like, servers?" Frank had all the traits of a young man in IT – beyond his physical appearance, he was brash, overconfident, and narcissistic. Throughout the brief interview, he didn't restrain any of these traits, but still, he was only vaguely interested in the position, so he winged all the questions. Ten minutes later, the man pulled out a marker, wrote something on a napkin, and slid it across the table. "That's what your hourly rate would be." The man arched his eyebrow. "Interested?"
Frank was already pulling in some respectable bank, but this was more than twice what he was currently making. Gears started turning in his brain while he mulled it over. Well, I guess if I was to take this jo-"YES." On his way home from the interview, Frank picked up a razor, stopped for a haircut, and generally got himself kempt.
The JobThe day after the interview, he was sitting opposite the Executive Vice President of Data Processing, who was giving a second interview. "Let's say I asked you to consolidate twelve server facilities into one. How would you do it?" Ahh, a riddle question, like "how would you move a mountain to the other side of a village?"
"Well," Frank started, winging his second interview in as many days, "I'd take a systematic approach. Figure out where everything was, how the different systems were integrated, how they communicate, and gradually migrate servers over."
The Bank Boss was clearly impressed since Frank was given a contract on the spot; no references or background checks. And not just that, Frank was given keycard access to everything – all of the different datacenters and various facilities. He didn't encounter anything his keycard didn't give him access to (though he never tried the bank's vault). He was also given passwords to every sensitive system, including the money transfer system, responsible for transferring money in the range of around one trillion dollars every day.
It quickly became clear that the interview question wasn't a hypothetical, and Frank was dealing with the impossible. And maybe that's why they hired him – he was an idealistic hard worker, a badass who could do anything. What he lacked in experience then he'd make up for in tenacity. At least that's what Frank was having a harder and harder time reminding himself.
And for better or for worse, he'd effectively be on his own. As it turned out, his team and the man that hired him were electricians. Back in those days, the bank (and, more importantly, their union contract) considered moving servers to be "electrical work" and, therefore, only union electrician companies were allowed to do it. Or those that the electricians hired.
The ProblemIn short, the bank had a dozen VAX datacenters that they wanted as a single cluster in a new building. Everything communicated over DECnet, which was a network protocol not too dissimilar from TCP/IP. One of the nice things about DECnet was the ability to route datagrams (packets) around the network in different ways to avoid failures, a fact which later proved to be useful.
The problem with the banks infrastructure was that either no one knew everything that was running in each datacenter, how it all worked, or how they'd work together in a single facility. Even worse, the people at the datacenters didn't want to talk to Frank, as the sooner Frank finished his job, the sooner they'd lose theirs.
The visits to the various datacenters always left Frank in a worse mood. All of them were in various states of disrepair – dirty, perhaps a flickering light, disorganized, but one stood above the others. Its floor was almost completely torn up due to a major renovation project following an asbestos contamination. All of the systems in this room were caked with dust, so much so that the labels were completely illegible. Only one system had lights blinking on its network port; so Frank brushed the dust off its label. "VDL-23 – Maintenance Test Box." Why does that sound so familiar?
Earlier that morning, Frank had done some network analysis, and found that all redundant links between the Money Transfer System and the other datacenters (aside from VDL-23) had been down for quite a while. Since DECnet routed around the failures and no one had thought to set-up network monitoring, no one had noticed that all of the other links had gone down. And before Frank discovered it, no one knew (or no one would tell him) where the box was physically. Immediately, Frank got cracking on a plan to bring the redundancy back online while keeping VDL-23 up, thanking the stars that the architecture of DECnet prevented the network from going down with all of the other servers. Still, something told him that the twisted, crushed, mistreated cables strewn across the floor might not remain reliable for transfers of $1T/day for long...
His watch alarm went off before he finished, it was a reminder that he had a mandatory meeting for all staff involved in the migration – about two hundred people in total. Frank rushed back to the main office, taking shortcuts using his everything-access keycard, and arriving just as the meeting was starting.
"Thank you all for coming," the executive vice president said, voice quivering, with a sweaty brow. "We're required to migrate the network to TCP/IP by the communications standard director." Frank winced.
The VP of communications chimed in, equally nervous. "Well... it's DECnet... it uses the non-routable LAT protocol. I... *ahem* we may need to push the deadline out..." The executive VP frowned, and asked for an update from the apps team.
The VP of Applications looked equally nervous, stammering out "we're still gathering information on the applications... and... we're not totally sure if we can actually run this all in one system..."
In a hushed tone, the executive VP took the floor again. "You're telling me we're going to miss our deadline. The board is very firm about our deadline. I'm not happy."
Frank craned his neck and looked around the room, everyone was staring at the floor. This was his moment. Once again feeling like a badass he rose from his seat dramatically, and in his most heroic voice, he boomed "There is a way."
Success!Three months later, a beautifully appointed datacenter hummed along, processing transfers and perfectly replicating all of the functionality from the former twelve separate datacenters. Pristine rows of computers and neatly arranged drive controllers worked dutifully, everything in perfect order. The board came through the datacenter to inspect the work, and left with no complaints. It had been completed on schedule and was looking great, everyone was happy.
Under the raised floor, the tangle of cables told the real story. What was really in that room was the original twelve datacenters, all of the systems sitting pretty on the raised floor, underneath which were piles of cables connected exactly the same way they'd always been connected, and with back-hauled communication lines running between the systems. As they say, out with the old, in with the old.
And off in one corner, on upgraded hardware, was VDL-23; still responsible for routing all of the money transfer traffic, now safely sitting in a datacenter where it would remain unperturbed.
"This coupon increased the chances of me trading in my car by about 0.79%," Josh notes.
"The rent looks okay to me," Stephan Rose writes, "but I'd be a bit unsure about being able to do the deposit."
"I know manufactures and consumers are demanding more out of today's batteries," Frank writes, "but this seems a little extreme."
"I received this on a birthday card," Ralph Nevins wrote, "I wonder how many tests they run?"
"I saw this on Amazon," wrote Ed Burnette, "but what if I want the Paperback edition?
"Apparently my last name is not appropriate," Andrew Young wrote, "the completely fake address I put is just fine though."
"I'm glad to know an error couldn't have happened," writes Ben Wyatt, "otherwise, I might think there was a reason I couldn't print that document."
"Such a deal," Angus Scott-Fleming said, "Pay $12/yr for 1 year, or $20/yr for 2 years, or $28/yr for three!"
"I don't know if checking the box puts DHS onto me," noted George, "but I figured that life's short enough as it is. I'd rather not influence the purchase of malware as much as its donation."
"The BBC website recently ran a report on children with weird names," Edd comments, "but I didn't expect them to actually employ one of the story's protagonists."
Rick worked for a regional ISP that provided hosting services. The customer base consisted primarily of consumers and small businesses, so the ISP offered a lot of "a la carte" services for things like SSL, authentication and database access.
A small chain of pet stores in the tri-state area, MegaPetCo, approached Rick's company because it was trying to expand into other cities and states. Having outgrown its current provider, MegaPetCo wanted Web space, a database and a few e-mail boxes. After careful consideration, it opted for the $74.99/ month Advanced Package that included a 10MB database, 100MB of disk space and 100GB of bandwidth.
After the switchover, it became apparent that what MegaPetCo needed far exceeded what it had ordered. For starters, its database ballooned to several gigabytes within the first month. On top of that, its Web traffic was far higher than the company's allotted bandwidth and other Web sites on the shared server were getting bogged down.
MegaPetCo opted to pay for overages, and its first monthly bill was astronomical: $4,281.32. Assuming that no one received the automated daily overage warning e-mails, the customer service rep offered to discount the bill and advised MegaPetCo to switch to a dedicated server. The owners of MegaPetCo, however, suspected the rep was "trying to pull a fast one" and instead opted to pay the bill, overages and all.
Behind the ScenesMegaPetCo had no problem paying outrageous hosting bills, but the company was upset that its Web site ran incredibly slow. Although Rick's company had long since dedicated a "shared" hosting server for MegaPetCo, it would still take upward of a couple seconds for a page to load.
Rick decided to look at MegaPetCo's code. He was surprised that the company's Web site, which required a several-gigabyte database, was very small. As it turned out, there was a good reason for that: it was a very simple PHP-based framework that housed virtually everything -- including other PHP files -- in the database.
Further investigation found that 98 percent of all the company's requests came from one set of IP addresses, which turned out to be its stores and home offices. Rick guessed that MegaPetCo had kiosks for something and perhaps ran some of its sales traffic through the database.
How little he really knew. The shared database for this Web site -- a 10MB file which was meant to power nothing more than a couple of blogs and small-traffic forums -- was the database for the entire company. The Web site itself accounted for less than 5 percent of the total data in MegaPetCo's database. The rest was home-office stuff, including POP sales registers, payroll, HR, inventory, tax records, and a kind of dynamic storage for invoices and maintenance tickets.
The database was incredibly simple: a single table with hundreds of columns. It probably had humble beginnings as a spreadsheet and organically grew into a vast monolith over the seven or so years that MegaPetCo was in business. If MegaPetCo wanted to find out what insurance it gave a truck driver five years ago, it was in the same table as the one serving up pictures of bird seeds for sale. All told, the database had millions and millions of rows -- had being the operative word.
Uh OhOne day, a developer was optimizing the database and removing records that MegaPetCo no longer needed. All it took was a single, poorly formed delete query to wipe out each and every row in the database table.
To say the developer panicked is akin to describing a quadruple amputation as a mere flesh wound. MegaPetCo's sales immediately ground to a halt. Along with everything else. Payroll, logistics, reporting, purchasing, you name it. Its Web site didn't work -- but that was the least of the company's worries. The status of its backups was bleaker still: None. Zip. Zilch. Nada.
The AftermathMegaPetCo blamed Rick's company. There was nothing the ISP could do, other than remind MegaPetCo that it had repeatedly advised the company to change services.
That didn't stop MegaPetCo from filing a lawsuit against Rick's company. Of course, it proved to be a bit of a challenge to sue without knowing how much money MegaPetCo actually had, so it simply withdrew the suit.
Unfortunately, the single delete query proved to be far more than MegaPetCo could bear. Within a few months, the company filed for bankruptcy and was forced to close every one of its stores -- laying off several hundred people along the way.
Death by Delete was originally published in the January 2009 issue of Redmond Developer News.
"Is this campus tech support?," the caller said before Michael even had a chance to say hello, "I hope this isn't a recording because we have a serious problem with one of the detectors here. It won't open files!!"
Used to working with the frantically confused user, Michael replied in a calming voice, "Now calm down, let's start out with your user id and—"
"THERE'S NO TIME FOR THOSE STUPID FORMALITIES!" the caller barked, "just make your way over to G-Building and go to B2. I'll meet you when you arrive. And, hurry!"
After the user hung up, Michael just stared at the receiver for a second before replacing it. G-Building was the chemistry department's and the basement levels (especially B2) was where the university had their real labs. The ones where all the researchers produced results that got published in various scientific journals.
Beside the fact that the entire building had their own dedicated support staff as a result of the occasional semi-secret stuff they did over there, it was 10:30 PM on a Sunday and they were calling about a problem with a... detector? That somehow wasn't able to open files?
Ordinarily, Michael would have deferred to a senior technician, but because of the late hour and the urgency in the caller's voice, he decided to go ahead and check into the problem himself. Michael prepared himself to face either the worst disaster... or the most outlandish IT related prank of his college career.
Getting Down and DirtyAs the elevator doors opened, Michael finally met — or rather, was seized by — his frantic caller, a bookish grad student in his late-20s named Jeffrey. "Thank goodness you're here," he huffed, "the lab's right around the bend, follow me!"
Michael had never been in the B2 level of Building-G and, as he followed Jeffrey, he started to wonder if that was a good thing. The dimly-lit, labyrinth-like corridors were lined with the occasional bright-red drum bearing various warnings with skull-and-crossbones insignia.
As they turned the corner towards another hallway with flickering and humming florescent lights, a large overhead sign flashed CONTAMINATED over and over again. "Don’t worry about that," Jeffrey said casually, "that's just the alpha radiation detector. It's been malfunctioning all week." It wasn't all that reassuring.
A few moments later, they arrived at a vault-like steel door labeled “Nuclide Laboratory.” The door opened with a loud creaking noise and revealed little more than a shabby room that seemed to double as a depot for discarded technology. Amidst the 386s and handful of Commodore 64s, another graduate student was sitting down, working on some papers.
Jeffrey explained that he and his lab mate were working on their dissertation which involved something about the detection of nuclear materials inside of a shipping container. During the course of several weeks, they had amassed all the data they would need, but had no way of retrieving it because the crotchety installation of Windows NT simply refused to recognize their USB pen drive. With their lab time running out, and no way to get their data off the PC, they were in panic mode.
After settling in, Michael recognized the computer immediately – it was a fairly vanilla model from about 8 years ago that he had owned before college. It had onboard USB and a good ol' Ethernet card. Piece of cake, he figured, however...it wasn't.
For starters, so far as he could tell, the installation of Windows NT4 on this particular gem was completely virgin and without any of the Service Packs applied. The maximum resolution was trapped at a visually nauseating 640x480x16, and, worse still, as indicated by a handful of error pop-ups after booting that basically said "Hey buddy! You've got the wrong device drivers installed!" the OS appeared to have been a forced transplant into the computer after first being installed on another PC.
Obiit Cum TesseraAlthough there was no access to the university’s network within the bowels of Building-G, Michael came prepared with a netbook PC and an Ethernet patch cable. He figured that at the very least it MUST have a working network card and that he’d be in and out with no issues, but instead, he quickly discarded that idea.
He attempted to run a hardware scan, but noticed that his login did not have administrative privileges. Fortunately, the Building-G network administrator was on call, so Michael dialed him up to get the system’s admin account.
"I have absolutely no idea," the network administrator confessed, "I didn't even realize that mutant NT PC even existed."
"Well then," Michael countered, "would you mind if I 'cracked the case' and take the hard drive back to the office and..."
The admin cut Michael off, "Actually, no offense, but I do mind" and went on further to explain that a lot of the equipment down there was held together with duct tape and wire (sometimes, quite literally), and was known to be "uniquely sensitive". "Moreover," he said in a hushed whisper, "when your primary users are semi-paranoid, fully tenured professors, having equipment (even temporarily) disappear, or worse, appear different - you can find how far clout can carry and make your life difficult and make your job disappear."
Instead, he advised Michael to contact the former Building-G admin: a recently-retired professor who likely still lived in the area. "Chances are," he added, "that old coot will remember the password."
However, there was a problem with the admin’s suggestion - Michael had attended the professor's funeral two weeks earlier.
Brute Force TacticsHaving neither a Ouija board nor a shovel, Michael was down to very few options and even less patience. The first and most obvious solution was to use his trusty Knoppix boot CD to extract the files off the NTFS drive, but some sort of strange, third-party encryption pretty much eliminated that option. One way or another, he'd have to login to the admin account.
Frustrated, Michael returned to the tech support offices and looked for alternate solutions. After some quick Googling found himself a promising, and very "L337 HAX0R" sounding, solution - he would use the Knoppix boot CD to download the password registry from the old PC, crack the admin pasword, and nurse it to health enough to pull the files off!
After burning the CD, he rushed back to the lab, pulled the password files off of the hard disk and took them home. Eager that the solution he found, so elegant in its simplicity, would help him, Michael started in with some of the dictionaries and rainbow tables (including some crazy foreign language ones). Nothing. Then it dawned on him - since the professor was likely an absolute genius (he was a nuclear scientist, for crying out loud) - the password was likely L&28A34G#$%GH1 or worse, something insane that somehow used non-printable ASCII characters. Finally feeling beaten and defeated, Michael figured he was at last out of options and decided, What the hell..With any luck, maybe it'll be done by next term, and put his computer to brute-forcing the >10 character password and went to sleep.
The next morning, Michael turned on his monitor was surprised, or perhaps shocked, to actually find the password displayed in the cracking software. What would be the lost admin password, what would be the code that he had, in a manner of speaking, pulled from the dead professor's head?
It was pretty simple: "spiderman911".
As quickly as possible, Michael gathered together all the NT patches and drivers he could think of, burned them onto a few CDs and raced to the Chemistry building. But this time, when Jeffrey let him through the B2 level, the grungy halls and rooms were filled with dozens of professors and grad students frantically working on their projects.
Remembering the lab admin describing the "peculiar" and regular users, Michael paused and decided not to install the updates Instead, he pulled out his Knoppix CD and booted up, and downloaded the data files onto the USB pen drive.
Before leaving, Michael decided to anonymously leave the CD on the computer desk with a short note describing how he had used it to save the data onto the USB drive. Hopefully, it'd come in handy for the next poor soul who needed to use a virtual crowbar to pry their data out of the dead professor's computer.
The Winds of Recession (from Juan Seul)
Among other things, my job description at a certain Austrian software company includes interviewing candidates for project manager, developer, and other IT positions. In all my years conducting interviews, I’ve never had one that was all too crazy, and to this day, I still haven’t. But I think I was pretty close.
One day, I had an applicant scheduled for an 11:00 AM interview. She had been downsized a few months ago from a local manufacturing company, and seemed pretty excited at the opportunity to work with my company.
As the time neared by, I took a break from what I was doing and waited for the front desk to call. The clock turned eleven. Then it turned five past. And then ten past. Finally, at quarter after, the front desk rang to say that the candidate had just cancelled the appointment.
“I asked when she’d be available for a reschedule,” the receptionist explained, “but she said she was no longer interested in the position. Apparently, she had walked halfway through the parking lot and found that it was far too windy for her. She just couldn’t see herself going to work through that kind of weather each day.”
A Doomed Interview (from John)
Times have been tough, so I've been looking just about evernwhere for work. Buried in the last page of the local newspaper, I found a tiny job ad seeking a candidate with several technologies I had experience with. Against my better judgment, I called the number and, after a few minutes of small talk, was invited to an interview. Not the next day, not the next week, but right then and there. Within hours, I found myself on a backwater industrial parkway, standing in front of a non-descript building.
Stepping through the front door was like entering a DooM level: dark as hell, a creepy bad atmosphere, and a slight fear that a giant spider was lurking around the corner. As my eyes adjusted to the gloom, it took all of three seconds to realize that I didn't want to work there. Against my better judgment, I headed in and up a dimly lit staircase.
The office was decrepit, devoid of people, and looked like a dingy basement with clutter, files, and junk strewn everywhere.What kind of a person would work here, I asked myself. Against my better judgment, I tapped on the door and called out "Hello?".
Within seconds, a podgy man wearing an ill-fitting shirt and high pants scuffled out from an office behind me. Introducing himself as the managing director, he offered to take me to the tech staff for an interview.
The managing director led me through some more cluttered areas, all which were barely illuminated with flickering bulbs. The atmosphere of silence and despair was overpowering, and no-one seemed to be around. That is, until and Bob appeared.
Tim was a ratty fellow, and Bob a bespectacled introvert who avoided eye contact. There was instant tension, the sort that arises when you intuitively know you have almost nothing in common. The interview started with awkward small talk – they didn’t like sports, they didn’t know what the weather was like, and they had no plans for the upcoming summer months – which lead into a rather long moment of uncomfortable silence.
During this I noticed an unnerving event. Oblivious to the interview, Tim froze for a few seconds and stared intently at an invisible point about two feet from his face. Suddenly, he scrunched his face like he'd eaten the sourest thing in the world. It was almost as if his face was collapsing inwards. Then he shook his head and returning to the interview.
Silence. Then Bob leaned over with a question: "How is your C++, like, are you good?"
I got out an answer about how I had been developing in C++ for years and felt very comfortable with it. And then another uncomfortable silence descended.
Just as I was about to mention STL, Tim asked when I would be available to start, to which I replied “within a week.” The interview ended after that question, and somehow I managed not to run from the office.
Needless to say, once outside, I drove away very quickly. Months later a letter arrived, apologizing for forgetting to inform me of the outcome of the interview. Somehow, I didn't get offered the job...
Oops! (from Drew S)
Having been laid off recently, I interviewed for a developer job at a local pyramid scheme matrix marketing Vacation Company. Within a few minutes of meeting Ray, the company’s COO, he told me that my university degree and six years of prior programming experience were meaningless. Especially when compared with their head IT guy, Phil.
It must have been my lucky day, because not only had Phil graced the office with his presence that afternoon, but was willing to grant me an audience. Shortly after Ray called him, Phil entered the conference room and nodded hello.
Phil began by asked me a few technical questions and then inquired if I had a portfolio available. As a matter of fact I did, so I proceeded to show him my online portfolio, which included all sorts of different code examples and libraries I had written.
“Whooooa there,” Phil stooped me, “we don’t do oop here.”
“I’m sorry,” I said, trying to figure out what “oop” meant, “you don’t do… oop? What do you– wait, do you mean object oriented programming.”
“Yah,” Phil responded, “it doesn’t really fit our business model”.
“Wait,” I was a bit confused, “you guys use ASP.NET; that’s an object-oriented framework.”
Phil scoffed and stood up. “I gotta get back,” he announced. Looking at me, he added “let me know if you have any non-oop code you can show. Then we’ll chat.”
Ray’s eyes intently followed Phil as he exited the conference room. “See what I mean,” he said in a mesmerized tone, “that guy is really hard core.”
I let the sound of silence be my response.
“Get him some code,” Ray said, looking back at me, “he might be willing to take you under his wing. But I’ll have to look at the books and see what makes sense from a hiring standpoint.”
I never got around to sending any “non-oop” code, but I did see their name on the local news a few months later. Something about deceptive sales practices, fraud, investigation, and that sort of thing. They’re not really around anymore, and I can’t say I’m upset by that.
JT Klopcic could not believe his eyes. It was supposed to be a simple assignment. The length of some data field was changing, so he needed to walk through the import process and make sure that all the associated data sizes would accommodate the new length.
JT was unfamiliar with the process, so he took a look at the import file. Thankfully, it was all well-formed XML. This should be rather easy, he thought. And then he stumbled over this:
// parse the XML data file if (File.Exists(StdFileName)) { // opens file for header data extraction. _sr = new StreamReader(StdFileName); FindHeaderString(_sr); // First line oHeader.FixABC = Convert.ToDouble(m_Textline.Substring(11, 6)); oHeader.FixDEF = Convert.ToDouble(m_Textline.Substring(19, 6)); oHeader.XYZ = Convert.ToDouble(m_Textline.Substring(26, 6)); oHeader.PDQs = Convert.ToDouble(m_Textline.Substring(33, 6)); oHeader.ChkIn = Convert.ToDouble(m_Textline.Substring(41, 6)); oHeader.DblFix = Convert.ToDouble(m_Textline.Substring(49, 6)); oHeader.DblUnload = Convert.ToDouble(m_Textline.Substring(57, 6)); oHeader.DblLoad = Convert.ToDouble(m_Textline.Substring(65, 6)); // Reads the next line and find the header string. if ((m_Textline = _sr.ReadLine()) != null) { FindHeaderString(_sr); // 2nd line oHeader.DelAdj = Convert.ToDouble(m_Textline.Substring(73, 6)); oHeader.PSPPerSt = Convert.ToDouble(m_Textline.Substring(82, 6)); oHeader.PSPPerPk = Convert.ToDouble(m_Textline.Substring(91, 6)); oHeader.PSPPerPg = Convert.ToDouble(m_Textline.Substring(100, 6)); oHeader.PSPPerSetup = Convert.ToDouble(m_Textline.Substring(108, 6)); oHeader.OffProp = Convert.ToDouble(m_Textline.Substring(117, 6)); oHeader.OnProp = Convert.ToDouble(m_Textline.Substring(126, 6));It was not going to be as easy as he thought.
Matt was excited: he had landed his first real web development job. Granted, it pretty far down on the totem pole – webmaster for a local wholesaler – but it was a foot in the door. Next job he might have the opportunity to do a little bit of PHP. And the job after that, maybe some MySQL. Soon enough, he’d be a full-fledged developer with a résumé overflowing with buzzwords from AJAX to Zend.
But for now, his job was to maintain the wholesaler’s website. Several years prior, the company had spent a bundle ($20K +) to have the site professionally designed by some local web development shop, and had been managing it in-house ever since.
As a whole, the website looked pretty decent… so long as you viewed it at 800x600. And used Internet Explorer 6. And didn’t scroll down before the page finished loading. Any deviation – such as browsing at 1024x768 – and the JavaScript-based navigation menu would throw the dropdown menu about four inches to the left of the page’s body. Or the right. Or, really, anywhere it felt like at the time, including out of view.
One of the main issues behind this was they had built the entire site with nested tables set to 757 pixels wide. The homepage, for example, had 19 tables nested within the main table, some of which had a width set to 1200 pixels. Naturally, that lead to all sorts of weird wrapping which would only be noticed if you happened use something other than IE6 at 800x600.
As for Matt, his first assignment was to tweak the layout so that it would work at other resolutions. And to do so without tearing up too much of the warped HTML code that the company had paid so much for.
His first attempt at fixing the layout was to use Dreamweaver: just paste everything in to a properly formatted table, nice and neat. After hitting CTRL-V, Dreamweaver threw up the hourglass for about five minutes and then finally exploded:
A few days later, while re-scripting the menus instead of reformatting the evil tables, Matt found a style sheet buried in an include file. It's filename? crm_useless.css. It also happened to live in a directory that Matt had not seen before, and where he found a full copy of the entire site, file for file.
It was definitely going to be a long way to the top.
Matt was excited: he had landed his first real web development job. Granted, it pretty far down on the totem pole – webmaster for a local wholesaler – but it was a foot in the door. Next job he might have the opportunity to do a little bit of PHP. And the job after that, maybe some MySQL. Soon enough, he’d be a full-fledged developer with a résumé overflowing with buzzwords from AJAX to Zend.
But for now, his job was to maintain the wholesaler’s website. Several years prior, the company had spent a bundle ($20K +) to have the site professionally designed by some local web development shop, and had been managing it in-house ever since.
As a whole, the website looked pretty decent… so long as you viewed it at 800x600. And used Internet Explorer 6. And didn’t scroll down before the page finished loading. Any deviation – such as browsing at 1024x768 – and the JavaScript-based navigation menu would throw the dropdown menu about four inches to the left of the page’s body. Or the right. Or, really, anywhere it felt like at the time, including out of view.
One of the main issues behind this was they had built the entire site with nested tables set to 757 pixels wide. The homepage, for example, had 19 tables nested within the main table, some of which had a width set to 1200 pixels. Naturally, that lead to all sorts of weird wrapping which would only be noticed if you happened use something other than IE6 at 800x600.
As for Matt, his first assignment was to tweak the layout so that it would work at other resolutions. And to do so without tearing up too much of the warped HTML code that the company had paid so much for.
His first attempt at fixing the layout was to use Dreamweaver: just paste everything in to a properly formatted table, nice and neat. After hitting CTRL-V, Dreamweaver threw up the hourglass for about five minutes and then finally exploded:
A few days later, while re-scripting the menus instead of reformatting the evil tables, Matt found a style sheet buried in an include file. It's filename? crm_useless.css. It also happened to live in a directory that Matt had not seen before, and where he found a full copy of the entire site, file for file.
It was definitely going to be a long way to the top.
Back in the early 90's, Marcus worked for a company we'll call SuperbNet. They were the European equivalent of CompuServe and a boasted a continent-wide network that you could dial-in to to post messages, share pictures, chat interactively, and so on. But unlike CompuServe, SuperbNet's infrastructure was built for reliability using specialized Tandem servers that could never fail.
For years, users were thrilled to pay upwards of $10/hr (on top of any long-distance charges) to access SuperbNet, and SuperbNet's Tandem systems — programmed with a customized version of FORTRAN — ran wonderfully. Because nothing ever seemed to break, the system was designed to go back years upon years to see everything that had ever been posted since first going online. It was as perfect of a world as could be. That is, until this thing named the "Information Superhighway" came along.
Re-Engineering the WheelEach month, more and more SuperbNet users were asking about the Internet. Some wanted to know what it was about while others demanded access to it. In neither case were the SuperbNet reps able to help. By the time customers started canceling their accounts, management took notice and decided to investigate what the Internet was all about.
The first thing management learned was that the Internet would not run on their venerable Tandem servers. Apparently, the Internet was built on Unix and if they wanted it, they'd have to upgrade. And they really wanted it. So they upgraded: each Tandem box would be replaced by a state-of-the-art Dual Pentium 60mhz running the state-of-the-art SCO Unix.
At least, that was the theory. As it turned out, SuperbNet's developers didn't really have any Unix systems background, nor did porting a custom FORTRAN compiler prove to be an easy task. So they coded. And they coded some more. And they coded and coded and coded until they had finally could compile their FORTRAN compiler in Unix and, as a result, compile their system on Unix. After quite a many months, things fell into place and they finally had something that resembled the current system.
Well, it kind of resembled the current system: a whole bunch of features were gone and those that remained ran really slow. The slowness wasn't a big deal: SuperbNet's userbase was shrinking and they could always add more servers. But the missing features started to become a problem: as it turned out, users really did like searching through years of old postings and they also liked sending each other files in formats other than BinHex. But most importantly, they really liked sending email.
One of the old system's main strengths was that it was able to tackle any kind of email messaging under the sun, from ARPANET to X.400. So long as it was publically accessible, there was some way to send and receive messages. However, when they did the Unix port, their old email system just wasn't working. It was something about low-level networking protocols.
Fortuntely, Unix and the Internet had already developed the gold standard for sending electronic mail over the Internet, sendmail. Unfortunately, no one at SuperbNet had any clue how to use it or, really, how it was even supposed to fit in to their system.
"So how do we get a sendmail," one of the programmers asked.
Another programmer confidently responded, "it comes on the Internet, which we have now."
"Okay," the programming manager chimed in, "but SCO said they do not support the Internet."
There was a bit of a paused. "Hmm," the first programmer replied, "I guess I can call. Does anyone have the phone number of the Internet so we can order a sendmail?"
Not surprisingly, no one was able to find the Internet's phone number. And although they were able get sendmail working eventually, it didn't make a whole lot of difference. By that point, proper ISPs were starting to appear and SuperbNet, who could not quite adapt to the "unlimited monthly" plans, ended up fading into a memory.
"I visited the Science Museum of London this week-end and saw this," Samuel Alba writes.
"Someone must have imported the sizing chart from an overeager Excel worksheet," writes Justin N.. "My girlfriend always considered herself a size 'May'."
"The AbeBooks book recommendation program seems to have escaped into the wild just a *little* too early," Steve Taylor writes. "Though 'BookAuthor01' has always been one of my favorite writers."
Graham wrote, "at Specialtech they understandably prefer phone numbers in scientific notation."
"I was looking to see how capable the Unix-to-Linux Migration is with Suse Linux," Anoop said, "I'm happy to report that it's undefined."
NPR Is Reading My Email (from Tom)
I was on a teleconference one day and saw another call coming through. It was Heather Jenkins, a fairly common caller to tech support, so I decided to send the call to voicemail. Whatever it was, it could wait.
As soon as my new voicemail indicator lit up, the phone rang again. It was Heather, so I sent the call to voicemail.
Moments later, the phone rang yet again. Guess who was calling. Since I was in the middle of the teleconference, I ignored it for the third time.
And then a new email popped up. "Tom, it's Heather, I need to talk to you pronto!!"
After my call ended, I dialed up Heather. In a frightened whisper, she explained that she had been listening to NPR while working and then noticed that, all of a sudden, NPR was reading aloud her email.
I was a little confused and asked her to elaborate.
"I know this sounds crazy," she said, "but one of the NPR newscasters is reading my email… live on the air… as I type it!"
I dropped everything and raced to her desk.
Wide-eyed and fearful, Heather opened up a new email and demonstrated this phenomenon.
I pointed out to her that she had Windows Narrator running. After explaining to her what Narrator is and how it works, she was momentarily relieved that the nefarious security agents of the NPR were not looking over her shoulder and broadcasting her Deep Thoughts.
And then she accusingly challenged me to explain how Narrator could have started itself.
Just Fix It! (from John Murphy)
I used to work as a night shift support agent for a web hosting company. We rarely saw our daytime counterparts, but we always sent a "sign off" email if anything needed to be addressed in the next shift. For fun, I sent the following message to the day tech before I left:
Except, instead of sending it to the day tech, I accidently emailed it H-Sphere Support, the vendor we use for our hosting automation software. Of course, the only way I realized this mistake was because I received an email about two hours later.
Subject: RE: Issues I'm sorry we didn't catch it earlier, but we fixed the config on the java proxy service and everything is working now!I have to say I was impressed. Sure, everyone has bugs in their software... but to fixed one we didn't even know we had based on a vague, somewhat rude email... now that's support.
The Engineer's Log (from Gabriel Luci)
Following is the log entry of a ticket that was submitted for a highly-paid Sr. Engineer:
Weekend Support (from Leif Davisson)
No matter how many pages of guides and manuals we write, our users always manage to find an area that we didn't cover. This is especially the case when someone takes a laptop home for remote work.
"My password isn't working," a recent weekend call I took started, "I think it's this keyboard."
"Without telling me your password," I responded, "why do you think it's the keyboard?"
"Well my password is sunshine1911," she said, "and I always type it in s-u-n-s-h-i-n-e then 1-9-1-1."
"Okay?" I questioned.
"There's no way for me to type 1-9-1-1 on this thing!"
After several minutes of back-and-forth, she swore up-and-down that the keyboard didn't have a 1, 2, 3, 4, or any of the other number keys. Only a F1, F2, F3, and so on.
All of our laptops are standard Dells, so it seemed a bit strange that hers had no number keys. She insisted hers had none, which we'd have to wait until Monday to resolve the issue.
First thing Monday morning, she brought her laptop over and pointed past the right of the keyboard. "See," she said, "this one doesn't have any numbers!"
She was a bit embarrassed when I pointed out the rows of numbers in between the letters and F-keys. At least we had something more to add to our manuals.
To many people, including Ron Owens, the word "some" refers to a relatively small amount in between "none" and "most". But To Ron's employer, and especially in the context of "job responsibly include... some maintenance of legacy VB6 applications", the word "some" tends to mean "pretty much all day long for the indefinite future."
Because legacy application maintenance is one of the torments found in the outer circles of hell, Ron had hoped to find catharsis by sending in examples of his day-to-day. But alas, because the application was so large and had been maintained by so many people, there was no single, concise snippet that faithfully represented what he was dealing with. That is, until recently, where he uncovered a snippet that not only illustrated the (over)complexity of the application but offers glimpse into what the UI looks like.
For Each LVRefWarnItem In Me.ListViewRefWarn.ListItems For Each LVDiagItem In Me.ListViewDiag.ListItems For Each LVReqdClassItem In Me.ListViewReqdClass.ListItems For Each LVReqdPayItem In Me.ListViewReqdPay.ListItems For Each LVReqdSpecItem In Me.ListViewReqdSpec.ListItems For Each LVReqingSpecItem In Me.ListViewReqingSpec.ListItems For Each LVSvcItem In Me.ListViewSvc.ListItems For Each LVReqdContItem In Me.ListViewReqdCont.ListItems For Each LVReqingContItem In Me.ListViewReqingCont.ListItems For Each LVReqingClassItem In ListViewReqingClass.ListItems For Each LVReqingPayItem In ListViewReqingPay.ListItems For Each LVHPCodesItem In ListViewHPCodes.ListItems For Each LVHPOptionCodesItem In ListViewHPOptionCodes.ListItems For Each LVPOSItem In ListViewPOS.ListItems For Each LVReqdProvIDItem In ListViewReqdProvID.ListItems For Each LVReqingProvIDItem In ListViewReqingProvID.ListItems For Each LVAuthTypeItem In ListViewAuthType.ListItems For Each LVMembCondItem In ListViewMemberCondition.ListItems TempDe1.InsertRule _ AdvancedRule, "Advanced", Me.TextGroup, Me.CheckAutoApprove.Value, _ CDate(Me.DTPickerFromDt), CDate(Me.DTPickerToDt), ExpDate, _ LVSvcItem.Text, LVSvcItem.ListSubItems(1).Text, LVDiagItem.Text, _ LVDiagItem.ListSubItems(1).Text, IIf(LVSvcItem.ListSubItems.Count = 1, _ "0", LVSvcItem.ListSubItems(LVSvcItem.ListSubItems.Count).Text), _ LVReqdSpecItem.Text, LVReqdSpecItem.ListSubItems(1).Text, _ LVReqdClassItem.Text, LVReqdClassItem.ListSubItems(1).Text, _ LVReqdContItem.Text, LVReqdContItem.ListSubItems(1).Text, _ LVReqdPayItem.Text, LVReqdPayItem.ListSubItems(1).Text, _ LVReqingSpecItem.Text, LVReqingSpecItem.ListSubItems(1).Text, LVReqingClassItem.Text, LVReqingClassItem.ListSubItems(1).Text, _ LVReqingContItem.Text, LVReqingContItem.ListSubItems(1).Text, _ LVReqingPayItem.Text, LVReqingPayItem.ListSubItems(1).Text, _ LVHPCodesItem.Text, LVHPCodesItem.ListSubItems(1).Text, _ LVPOSItem.Text, LVPOSItem.ListSubItems(1).Text, _ LVReqdProvIDItem.Text, LVReqdProvIDItem.ListSubItems(1).Text, _ LVReqingProvIDItem.Text, LVReqingProvIDItem.ListSubItems(1).Text, _ TextDesc.Text, TextAgeFrom.Text, TextAgeTo.Text, _ LVAuthTypeItem.Text, LVAuthTypeItem.ListSubItems(1).Text, _ LVMembCondItem.Text, LVMembCondItem.ListSubItems(1).Text, _ Me.cboRuleType.SelectedItem.Key, Me.txtRulePriority.Text, _ Int(LVRefWarnItem.Text), Int(LVRefWarnItem.ListSubItems(1).Text), _ LVHPOptionCodesItem.Text, LVHPOptionCodesItem.ListSubItems(1).Text Next Next LVAuthTypeItem Next LVReqingProvIDItem Next LVReqdProvIDItem Next LVPOSItem Next LVHPOptionCodesItem Next LVHPCodesItem Next LVReqingPayItem Next LVReqingClassItem Next LVReqingContItem Next LVReqdContItem Next LVSvcItem Next LVReqingSpecItem Next LVReqdSpecItem Next LVReqdPayItem Next LVReqdClassItem Next LVDiagItem Next LVRefWarnItemChest puffed out and walking absurdly fast, Dietrich called out various rooms as they passed. "Built in the 70s, you'll find our building is an absolutely stunning marvel – processing room! – of modern architecture. Top to bottom, function has – restroom! – dictated the form. You'll find no unnecessary extravagences – another restroom! – within these walls." His heels clicked and echoed as he led Chris S. and another fresh-faced recruit on the grand tour of RNTP's corporate building.
Chris had been trying to get a word in, and seized the opportunity as soon as he could. "Wow, this building is hu-"
"EXCUSE me," Dietrich's steps came to an immediate halt as he turned and gave Chris the stink eye. "Moving on. You will have no trouble finding – executive conference room! – your way around."
Their journey ended in front of a dark gray steel doorway with DICT flawlessly painted on the front. "This room is a shining example of what we intended," he said, dramatically opening the door to the sound of groaning metal. Chris and the other recruit stepped in to the room. It was drab, gray, dimly lit, and lined with empty shelves. There were no signs that the room had ever seen any use; no scuffs or chips in the floor, no marks on the countertop that jutted out from the south wall, not a speck of dust in sight. From about waist height to the ceiling, there were dozens of shelves that were deep but only a few inches tall. Two fully-stocked latex glove dispensers were mounted on the walls near the shelves for no reason that Chris could determine. No wallcoverings, no windows, just a cavelike bleakness wall to wall, floor to ceiling.
Dietrich eyed the men expectantly, so Chris let out a nervous smile. "You're impressed. Not surprising, this room is just wonderful. And the best news is that you gentlemen will get to work in this very room!"
Losing TimeWhether it was 7:00 in the morning or 7:00 in the evening, any sense of time had slipped away from Chris. His dark, windowless chamber always looked the same. Visits from his supervisor were few and far between and his fellow newbie's social anxiety kept him silent for much of the day. It was an internship spent in solitary confinement. Chris began tallying the days in his notebook.
On day 26, at what would have been sunrise, the door groaned open to Dietrich's face. "How are you sirs doing?" Chris's co-worker barely even looked up in acknowledgement. "Fi-," Chris began.
"This room has some great history," Dietrich interrupted, wide-eyed. "This was designed perfectly to accomodate a project." Maybe a project to see how long it would be before Chris or his colleague would go crazy and kill and eat the other? "We were working on a dictionary."
Chris blinked, and the room was silent. "So why-"
"We knew it would be a big one. 50,000 entries or so. Each entry would have three to five quotations. So, let's say, 250,000 quotations. Each quotation on its own punch card," he paused. "I mentioned this was years ago, right?"
"Actuall-"
"So all these shelves were planned to perfectly fit all these punch cards!"
By the time the building was completed, punch cards weren't even used by any of the company's systems anymore, but the room stands strong as a reminder of outdated technology. The shelves had been built to accomodate 41,945 cubic inches of punch cards, and had never seen hide nor hair nor hanging chad of a single punch card.
Chris continued his internship for another 38 tally marks, bringing his three months to a close. On his way out, Dietrich walked just as quickly, and his footsteps echoed exactly the same. As they moved past a door that Chris walked past every day, marked "VAX," he noticed the door was open. On his first tour when he started, the room contained a collection of VAX mainframes sitting on a raised floor. Now the room had a single small server off in a corner of the room. Yet again, a room's design had been made obsolete.
Fortunately, work has begun on a new room designed to store all of RNTP's Jaz disks; construction will be complete in the summer of 2023.
"This was the packing slip on a package I received from some online order," Florian Schicker writes, "apparently, the Chinese folks writing these slips don't have computers that can display the 'ö' character."
Roger found this while poking around some Microsoft code in Reflector.
"Well then," wrote K. Bear, "I guess I won't be logging in."
"I received this award while playing the good ol' Theme Hospital," Christian notes, "I wonder if I should have been playing an FPS instead."
"I got this while copying a file from a spanned zip archive," Trev writes. "I think I need a bigger HDD."
John Dorn's colleague's approach to problem solving is best described as follows. The solution to any given problem is to introduce two additional problems. While this approach generated quite a many interesting implementations, it rarely produced the needed results: simple, custom software for their clients. Ultimately, this approach led towards his de-hiring, which meant that John would have to maintain his old systems.
One project that John inherited was a fairly simple web application that tracked overtime. Simple, that is, from the front end. The back end PHP code was responsible for querying a MySQL database with queries similar to this:
SELECT * FROM bean_overtime_availability WHERE `startDateTime` >= DATE(NOW()) AND `available` = 1;Seems simple enough, right? Here's the code used to generate that query.
public function getOvertimeAvailability() { $c = new Criteria(); $c->leftParenthesis(); $c->field('startDateTime'); $c->greaterThanOrEqualTo(); $c->quote($this->getToday()); $c->rightParenthesis(); $c->andCriteria( Criteria::newCriteria()->field('available')-> equal()->quote(1) ); $c->addString(' order by startDateTime;'); return $this->getPersistenceLayer()-> selectBeans($this->getOvertimeAvailabilityBeanDefinition(),$c); }Thinking that the code looked far too simple, John assumed the Criteria class was a kind of magical black box that performed some kind of SQL-fu to make things a lot easier / more efficient. And then he peeked into the Criteria class.
class Criteria extends Object { protected function add($c) { $this->getList()->add($c); } protected function getList() { if (is_null($this->list)) $this->list = new ArrayList; return $this->list; } public function leftParenthesis() { $this->add('('); return $this; } public function rightParenthesis() { $this->add(')'); return $this; } public function comma() { $this->add(','); return $this; } public function space() { $this->add(' '); return $this; } public function quote($text) { $this->add("\"$text\""); return $this; } public function field($text) { $this->add("`$text`"); return $this; } public function equal() { $this->add('='); return $this; } public function null() { $this->add('null'); return $this; } public function in() { $this->add('in'); return $this; } public function not() { $this->add('!'); return $this; } public function notEqual() { $this->not(); $this->equals(); return $this; } public function lessThan() { $this->add('<'); return $this; } public function lassThanOrEqualTo() { $this->lessThan(); $this->equals(); return $this; } public function greaterThan() { $this->add('>'); return $this; } public function greaterThanOrEqualTo() { $this->greaterThan(); $this->equal(); return $this; } public function addCriteria($c) { $this->leftParenthesis(); $this->add($c->toString()); $this->rightParenthesis(); return $this; } public function operator($operator) { $this->add($operator); return $this; } public function andCriteria(&$c) { $this->add('and'); $this->leftParenthesis(); $this->add($c); $this->rightParenthesis(); } public function orCriteria(&$c) { $this->add('or'); $this->leftParenthesis(); $this->add($c); $this->rightParenthesis(); } public function addString($str) { $this->add($str); return $this; } public function toString() { return implode('',$this->getList()->getItems()); } static function newCriteria() { return new Criteria(); } }John Dorn's colleague's approach to problem solving is best described as follows. The solution to any given problem is to introduce two additional problems. While this approach generated quite a many interesting implementations, it rarely produced the needed results: simple, custom software for their clients. Ultimately, this approach led towards his de-hiring, which meant that John would have to maintain his old systems.
One project that John inherited was a fairly simple web application that tracked overtime. Simple, that is, from the front end. The back end PHP code was responsible for querying a MySQL database with queries similar to this:
SELECT * FROM bean_overtime_availability WHERE `startDateTime` >= DATE(NOW()) AND `available` = 1;Seems simple enough, right? Here's the code used to generate that query.
public function getOvertimeAvailability() { $c = new Criteria(); $c->leftParenthesis(); $c->field('startDateTime'); $c->greaterThanOrEqualTo(); $c->quote($this->getToday()); $c->rightParenthesis(); $c->andCriteria( Criteria::newCriteria()->field('available')-> equal()->quote(1) ); $c->addString(' order by startDateTime;'); return $this->getPersistenceLayer()-> selectBeans($this->getOvertimeAvailabilityBeanDefinition(),$c); }Thinking that the code looked far too simple, John assumed the Criteria class was a kind of magical black box that performed some kind of SQL-fu to make things a lot easier / more efficient. And then he peeked into the Criteria class.
class Criteria extends Object { protected function add($c) { $this->getList()->add($c); } protected function getList() { if (is_null($this->list)) $this->list = new ArrayList; return $this->list; } public function leftParenthesis() { $this->add('('); return $this; } public function rightParenthesis() { $this->add(')'); return $this; } public function comma() { $this->add(','); return $this; } public function space() { $this->add(' '); return $this; } public function quote($text) { $this->add("\"$text\""); return $this; } public function field($text) { $this->add("`$text`"); return $this; } public function equal() { $this->add('='); return $this; } public function null() { $this->add('null'); return $this; } public function in() { $this->add('in'); return $this; } public function not() { $this->add('!'); return $this; } public function notEqual() { $this->not(); $this->equals(); return $this; } public function lessThan() { $this->add('<'); return $this; } public function lassThanOrEqualTo() { $this->lessThan(); $this->equals(); return $this; } public function greaterThan() { $this->add('>'); return $this; } public function greaterThanOrEqualTo() { $this->greaterThan(); $this->equal(); return $this; } public function addCriteria($c) { $this->leftParenthesis(); $this->add($c->toString()); $this->rightParenthesis(); return $this; } public function operator($operator) { $this->add($operator); return $this; } public function andCriteria(&$c) { $this->add('and'); $this->leftParenthesis(); $this->add($c); $this->rightParenthesis(); } public function orCriteria(&$c) { $this->add('or'); $this->leftParenthesis(); $this->add($c); $this->rightParenthesis(); } public function addString($str) { $this->add($str); return $this; } public function toString() { return implode('',$this->getList()->getItems()); } static function newCriteria() { return new Criteria(); } }