Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2024-11-22 03:01
News Roundup: UI That Looks Like $900 Million Bucks
User experience, and its related topic of user interface design, are important. How important? Well the US government’s General Service Administration (GSA) took the time to build a website to explain what it is. What other proof do we need? Well not only did the GSA build a website, but they invested in the SEO necessary to make it top of Google organic search, right below the featured snippet from interaction-design.org. Which is why the saga and ongoing story of Citibank’s debt repayment blunder all the more amazing. Here’s a quick recap:
Error'd: {Obscure Reference Here}
Today's Error'd submissions all center around another common pitfall of the modern web application: failed text substitutions and the ensuing unintentional hilarity.Antipodean Tony B. sends a Scot sir slur, writing "The mighty Beeb dumbs it down?"
CodeSOD: Reaching for Private Parts
Jaco was adding some caching to a Java application. Quite wisely, Jaco wrote plenty of tests around his change, ran the test suite, and confirmed everything was green. It ran fine in testing, but when it went to production, everything failed.Well, as it turned out, the configuration for the production environment loaded slightly different Java classes. One of those "only-loaded-in-production" modules did this:
CodeSOD: Not Exceptional
One of the powers of structured exception handling is that it lets you define your own exception types. That's useful, as your code can communicate a lot of information about what's gone wrong when you use your own custom exceptions.But sometimes, the custom exception type leaves us asking more questions. Christophe found this Java code from a "big application for a big company".
CodeSOD: Two Knowing Comments
Sometimes, it really is the comment which makes the code. Sometimes, the comments make simple (but still more complex than it needs to be) code less clear.For example, Thomas provides this code, and comment, which… I understand what is happening here, despite the comment:
CodeSOD: A Big Raise
Everyone likes getting a pay raise. Well, I suppose it depends on why. And HR isn't going to be too happy about your raise if it comes as the result of an easy-to-avoid software bug.Cédric V's company makes payroll software mostly used in and around France. One of their customers had a problem: when paying employees, it would give them a significant raise- sometimes by two orders of magnitude, rarely by three or four.What was surprising is that this happened to one customer, but none of their other customers. They couldn't replicate it on their test environment either. But once Cédric started digging into the code, it wasn't hard to understand what the root cause was.
Error'd: 4'33"
It's hard to define what makes today's batch of submissions so special. Is it just the futility? Or is it the certainty that nobody nowhere knows nothing?Audiophile Neal S. tentatively asserts "Not sure this is where the lyrics are supposed to be on the Spotify UI."
CodeSOD: A Range of Skills
Ulvhamne works on a team with over a hundred other developers. It's a big group, working on a huge project. And some of the quality in that code base gets… variable. Worse, when a bug pops up, it can be tricky to even identify what in the code is triggering the bug, let alone what the root cause is.For example, one of the config-file fields needed a number to specify the beginning and end of a range. If you put in a relatively short range- thousands or hundreds of values- everything worked fine. That was a pretty typical use case. But if you put in something closer to MAX_INT, everything worked fine for a little bit, but within moments the server would grind to a halt, memory would fill up, and the OS would hang as it ended up constantly thrashing pages to disk.Ulvhamne joked with one of his co-workers. "Wouldn't it be funny if, instead of just tracking the range's endpoints, they populated an array with all the possible values instead?"
CodeSOD: A Type of Code
Like the war between Emacs and Vim, developers also tend to wage a war between "strongly typed" and "loosely typed" languages. There are tradeoffs either way, and I think that's why you see things like TypeScript and Python's type annotations starting to creep into loosely typed languages- types when you need them, but not required. But if you're not comfortable with types, and don't really understand type casting, you might start writing some code like, well, like these examples.Sashi found this C# code:
CodeSOD: A Type of Code
Like the war between Emacs and Vim, developers also tend to wage a war between "strongly typed" and "loosely typed" languages. There are tradeoffs either way, and I think that's why you see things like TypeScript and Python's type annotations starting to creep into loosely typed languages- types when you need them, but not required. But if you're not comfortable with types, and don't really understand type casting, you might start writing some code like, well, like these examples.Sashi found this C# code:
CodeSOD: Leave Some Comments Behind
We have a lot of stories about the code coming from offshore/outsourced developers being of low quality. Today, Radu S sends us the reverse. He used to work for one of those offshore development shops. A customer started development in-house, and then decided that they didn't want to support their own code anymore, and shipped it off to Radu's company.This block represents what he's working with:
CodeSOD: Last One In
A lesson that everyone learns at some point is "don't write your own authentication code." Authentication, like encryption, and like dates, is incredibly complex and has all sorts of ways you can subtly mess it up and not realize your mistake.Take, for example, this code from Christopher. His peer wrote this code, added a single test record to the database, saw that it worked, and called it a day.
Error'd: And then I gave him my digits.
Franz K. anonymously ponders the meaning of existence after this encounter
CodeSOD: Double Your Value
There are many ways to debug your code. You might use an actual graphical debugger, wrestle with GDB, just spam print statements, or rely on a logging framework to help you generate useful diagnostic output.Since you're going to need some logging output no matter what, it's always good to heavily instrument your code. Using logging levels, you can control quite well what gets dumped when. Well, "LostLozz" had a co-worker who found an… interesting way to control logging.
CodeSOD: The Secret to Success
"I was once working for a company that primarily dealt with Oracle products," Tai writes.That vendor, who shall not be named again, provided an installer. Tai ran it, and it failed. Since the installer was a shell script, she opened up the file and took a look.
CodeSOD: A Terned Around Discount
If you browse the Errords, it's easy to see that "giving customers a discount" is apparently harder than it looks.Brian's company had one of those "discounts are hard" problems, way back when. Sometimes instead of a discount reducing the price, it would raise it. The root cause was that the sales team setting up the promotions weren't clear about whether the discount amount should be a negative or positive number. Instead of adding validation to ensure they always entered a negative (or at least, a zero amount), one of Brian's predecessors fixed the bug in their C# like this:
Worlds Collide
George had gotten a new job as a contractor at a medium-sized book distributor. He arrived nice and early on Day 1, enthusiastic about a fresh start in a new industry.His "office" turned out to be a huge warehouse stacked high with books. Upon greeting him, his manager pointed him to a PC in the corner of the warehouse, sitting on a desk with no partitions around it. The manager leaned over the machine and made a few double-clicks with the mouse until he opened up the H: drive. "There you go," he muttered, then left.George stared after him, perplexed, wondering if the manager intended to bring over coffee or other coworkers to meet him. The way he was walking, though, seemed to convey that he had more important things to be doing than coddling greenhorns."You must be George. Hi, I'm Wally." Another gentleman came over with his hand poised to shake. "I handle the software we use to track inventory. Let me show you the ropes."Wally used the nearby computer to demonstrate a handful of the 200-odd Delphi forms that constituted the inventory application. The source code was not in any kind of source control; it was all in a folder named Wally on the shared H: drive. They were using a version of Delphi from 1995 ... in 2010. Their database was some vague, off-brand SQL-esque construct that George later learned had been dropped from support as of 2003.None of this inspired George's confidence, but he had a job to learn. Stifling a sigh, he asked Wally, "Could I have a copy of your database creation script? Then I could start with a fresh and empty database to learn on.""No problem. Come with me."Wally led George to another part of the warehouse where a different computer was set up; presumably, this was Wally's desk. Wally sat down at the machine and began typing away while tapping his foot and whistling a little tune.This went on, and on ... and on. It certainly didn't seem like the quick typing one would do to create an email with an attachment. George shifted his weight uneasily from one foot to the other. As the rhythmic typing and whistling continued, it hit him: Wally was typing out the entire CREATE DATABASE code—from memory.It took Wally a good 25 minutes to bang out everything needed to define 60-odd database fields including Title, ISBN, ISBN-19, Author, Publisher, etc. Finally, the one-man concert ceased; Wally sent the email. With a perfectly normal look on his face, he faced George and said, "There it is!"In the moment, George was too flabbergasted to question what he'd witnessed. Later, he confirmed that Wally had never even thought to have a saved CREATE DATABASE SQL script on hand. Sadly, this was far from the last point of contention he experienced with his coworker. Wally could not comprehend why George might want some general utility functions, or a clean interface between modules, or anything more advanced than what one found in chintzy programming manuals. George's attempts at process improvement and sanity introduction got his building access card invalidated one morning about a month after starting. No one had expressed any sort of warning or reproach to him beforehand. George was simply out, and had to move on.Move on he did ... but every once in a while, George revisits their old website to see if they're still in business. At the moment, said website has an invalid certificate. For a company whose whole business came down to head-scratching practices heaped upon 15 year-old unsupported tools, it's not so surprising. [Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!
Error'd: The Sound of an Unheard Treefall
Brett N. starts us off today with a timely notification that he received late on the 24th
CodeSOD: A Bit of Power
Powers of two are second nature to a lot of programmers. They're nearly inescapable.Equally inescapable are programmers finding new ways to do simple things wrong. Take Sander's co-worker, who needed to figure out, given a number of bits, what's the largest possible value you could store in that number of bits. You or I might reach for our language's pow function, but boy, in C++, that might mean you need to add an include file, and that sounds hard, so let's do this instead:
News Roundup: We're Going to Need a Bigger Boat
CodeSOD: A Lack of Progress
Progress bars and throbbers are, in theory, tools that let your user know that a process is working. It's important to provide feedback when your program needs to do some long-running task.Hegel inherited a rather old application, written in early versions of VB.Net. When you kicked off a long running process, it would update the status bar with a little animation, cycling from ".", to "..", to "...".
CodeSOD: Self-Documented
Molly's company has a home-grown database framework. It's not just doing big piles of string concatenation, and has a bunch of internal checks to make sure things happen safely, but it still involves a lot of hardcoded SQL strings.Recently, Molly was reviewing a pull request, and found a Java block which looked like this:
Error'd: The Timing is Off
Drew W discovers that the Daytona 500 is a different kind of exciting than we ever thought.
CodeSOD: Spacious Backup
Today's anonymous submitter works on a project which uses Apache Derby to provide database services. Derby is a tiny database you can embed into your Java application, like SQLite. Even though it's part of the application, that doesn't mean it doesn't need to be backed up from time to time.Our submitter was handed the code because the backup feature was "peculiar", and failed for reasons no one had figured out yet. It didn't take too long to figure out that the failures were triggered by not having enough space on the device for a backup. But they definitely had a enoughFreeSpaceForBackup check, so what was going wrong?
CodeSOD: Shorely a Bad Choice
"This was developed by the offshore team," is usually spoken as a warning. There are a lot of reasons why the code-quality from offshore teams has such a bad reputation. You can list off a bunch of reasons why this is true, but it all boils down to variations on the Princpal-Agent Problem: the people writing the code (the agents) don't have their goals aligned with your company (the principal).Magnus M recently inherited some C# code which came from the offshore team, and it got principal-agented all over.
CodeSOD: Optimized
In modern times, there's almost no reason to use Assembly, outside of highly specific and limited cases. For example, I recently worked on a project that uses a PRU, and while you can program that in C, I wanted to be able to count instructions so that I could get extremely precise timings to control LEDs.In modern times, there's also no reason to use Delphi, but Andre found this code a few years ago, and has been puzzling over it ever since.
The Therac-25 Incident
Error'd: Sweet Sweet Summertime
Gastronome Carl hungrily drools "I haven't measured the speed of a snail but it's gotta be close."
CodeSOD: Self Improvement in Stages
Jake has a co-worker named "Eddie". Eddie is the kind of person who is always hoping to change and get better. They're gonna start eating healthier… after the holidays. They're gonna start doing test driven development… on the next project. They'll stop just copying and pasting code… someday.At least, that's what we can get from this blob of code.
CodeSOD: Stocking Up
Sometimes, you find some code that almost works, that almost makes sense. In a way, that's worse than just plain bad code. René was recently going through some legacy JavaScript code for their warehouse management system.Like any such warehousing system, there's a problem you have to solve: sometimes, the number of units you need to pick to complete the order is larger than the stock you have available. At that point, you need to make a decision: do you hold the order until stock comes in, do you partially fill it and then follow up with a second shipment, or do you perhaps just cancel the order?René found a line like this:
The Economic Problem
One of the main tasks any company needs to do is allocate resources. Regardless of the product or the industry they're in, they have to decide how to employ the assets they have to make money. No one has really "solved" this problem, and that's why there are swarms of resource planning systems, project management tools, and cultish trend-following.After a C-suite shuffle at James B's employer, one of the newly installed C-level execs had some big ideas. They were strongly influenced by one of the two life-changing books, and not the one involving orcs. A company needs to allocate resources. The economy, as a whole, needs to allocate resources. If, on the economic level, we use markets to allocate resources because they're more efficient than planning, then we should use markets internally as well.For the most part, and for most groups in the company, this was just a book-keeping change. Everyone kept doing the same thing, but now instead of each department getting email accounts for every employee, each department got a pile of money, and used that to pay for email accounts for each employee. Instead of just getting a computer as part of the hiring process, departments "rented" a computer from IT. It created a surprising amount of paperwork for the supposedly "efficient" market, but at least at first, it wasn't a problem.Before long, though, the C-suite started to notice that a lot of money flowed in to the IT department, but very little flowed back out. The obvious solution, then, was to cut the IT budget entirely. It would fund itself using the internal market, selling its services to other departments in the company.The head of IT reacted in a vaguely reasonable way: they jacked the internal billing rates as high as they could. Since they technically owned the PCs, they installed them with physical locks on the cases. If you wanted a hard drive replacement, you needed to go through IT. The problem is that IT had exclusive contracts with vendors, and those vendor SLAs were pretty generous- to the vendors. One HDD failure could take a PC down for weeks while you waited for a replacement.James was a victim of one such incident. While using a loaner PC to do his work, he and his boss Krista, got to talking about how frustrating this was. They were, after all, a software development team, and "having access to a computer, with all our software installed" was a priority."It makes me want to break the lock and replace the drive myself," James said. "It'd probably be cheaper too."Krista laughed. "It'd be a lot cheaper. Heck, I could just buy you a new computer for what they charge to replace a hard drive."Krista paused, then started mentally running the numbers. "Actually… I could do that." She immediately called a local vendor, a small company, and ordered a laptop for James. It arrived the next day, and once James set it up with his network credentials, he had full access to all the other IT services, like the shared drives.Krista's team was one of the smaller teams in the company, but they needed a lot of IT services. Billed at the internal billing rates, that was a significant amount of money, and a big chunk of IT's budget came straight from Krista. But if she shopped around on her own, she could get everything- hardware, software licenses, basically everything but company email addresses and login credentials, for a fraction of the price.And that's exactly what Krista did. She went through her department and found every piece of hardware they "leased" from IT, from PCs to network switches to even the cables, and replaced them.The IT department wasn't happy about this. Most of their monthly spend was overhead that didn't change just because one tiny department stopped using their services. With Krista's team cutting off their funding, this meant IT had a budget crunch. Worse, other teams were starting to grumble.This lead to a call where the head of IT laid out an ultimatum to Krista: "If you don't purchase your infrastructure from us, we will cut off your team's access to the network entirely. You can't just be plugging in any device you like to the network, it's bad for security.""That's fine," Krista replied. "We can work on our own private LAN, and when we need to give software releases to the distribution team, we'll just walk down the hall and drop off a thumb drive or a CD, instead of using the network drive.""You can't do that!""Why not? You're trying to bill me six figures a year to deliver a service I can replace with a short walk down the hall."While the war between Krista and IT raged, elsewhere in the company, similar battles played out. Krista may have fired the first shot, but the internal market became a war zone.The division which made Product Line A had no interest in selling Product Line B, despite the products being complimentary; their budget only made money when they sold A. Other departments tried to internalize other corporate functions- one department tried to spin up its own HR department, another stopped doing its primary job and just started selling accounting services to other departments. One of their hardware departments discovered that they could shift to reselling competitors products and make more money that way, so they did.Within a year, the internal market was canceled. The C-level executive who had pushed for it had already moved on to another C-suite in another giant company, and was still preaching the gospel of the internal market. Without that influence, James's company instituted a new "Company Family" policy, which promised "no departmental boundaries". People still used internal budgeting to help them allocate resources, but gone were the big piles of money that could just be spent however. No department was trying to make money off other departments. The grand experiment in internal capitalism was over. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
News Roundup: Flash Point
With nearly one month of 2021 in the books and the spectre of Covid-19 exhausting all of us, let’s do a quick inventory of the memorable moments of the past three months, shall we?
Error'd: We're Number 0th
Drinker Philip B. confesses "The first bottle went down fine but after the second my speech got a little schlurred ..."
Coming to Grips
Regardless of what industry you're in, every startup hits that dangerous phase where you're nearing the end of your runway but you still haven't gotten to the point where you can actually make money with your product. The cash crunch starts, and what happens next can often make or break the company.Nathan was working for a biotech company that had hit that phase. They had a product, but they couldn't produce enough of it, cheaply enough, to actually make a profit. What they needed was some automation, and laboratory robots were the solution. But laboratory robots were expensive, and for a company facing a cash crunch, "expensive" was too risky. They needed a cheaper solution.So they found Roy. Roy was an engineer and software developer, and Roy could build them a custom robot for much cheaper. After all, what was a lab robot but an arm with a few stepper motors and some control software? Roy turned around and shipped them a 2-axis robotic gripper arm ahead of schedule and under budget.When Nathan joined the team, the arm wasn't working. Or, well, it kinda worked. Like a lot of such systems, the gripper had a "home" position. Between tasks, the gripper needed to return to that home position, and the way it was supposed to know that it was there was by checking a limit switch- a physical "button" that the arm would touch, telling the motor-control board that it should stop moving the arm.For some reason, during the homing operation, the arm would stutter its way over, constantly stopping at random intervals, jerking and making godawful noises along the way. Nathan got Roy on the phone to talk through the symptoms and what was going on."So, when I was testing these," Roy said, "I found a fault in the motor-control boards. I think it's the whole batch of them, because every one I tried had the exact same behavior."Nathan asked Roy to repeat that. "You think the entire lot of motor controllers you ordered from the vendor have QA failures?""It's the only explanation," Roy said. "It's certainly not anything in my software or any of my custom parts."Nathan was almost certain that wasn't true.Nathan examined the hardware while Roy continued his explanation. "So, anyway, what I was seeing was that the motor controller will report the home switch is hit, even when absolutely nothing is touching the home switch. So I added a work around; when the motor controller tells my software the switch is hit, I stop the motor, but then check to see if the switch is actually hit- and if it isn't, I keep moving.""So, wait, when you stop the motor, the incorrect data goes away?""That's what I found in testing, yeah."Nathan examined the wiring that connected the motor controller to the rest of the hardware- specifically the stepper motors and the limit switch. Roy had obviously wanted to keep his design "neat and clean", because he used a single, multi-conductor cable. From there, it wasn't hard for Nathan to figure out what was going on.Some of the wires in that connector were just power and ground. One was for the limit switch- it'd read "high" if the switch were hit, and "low" otherwise. And the others were for the stepper motors. All of these wires were crammed together, with only a thin layer of insulation between them. The problem with that design was that stepper motors are controlled by sending PWM signals down the wire. Time-varying electrical fields have this seemingly magical power to induce current in other fields, which is a fancy way of saying "putting PWM signals on one wire can induce current in a nearby wire", and also is one of the basic principles which anyone doing electrical design should know.When the homing operation told the steppers to move, the signal to the steppers created interference in the home switch wire, causing the motor controller to think the home switch had been hit. By stopping the steppers, Roy stopped the interference, so the interference stopped, and now the system could continue.The fix was also simple: Nathan replaced the single multi-conductor cable with two shielded cables, isolating the home switch wire from interference.As a bonus example of what you get when you hire Roy, Nathan also supplied some of the sample code in Roy's custom robot scripting language. This sample promises to show you how to weigh every vial in a rack of vials:
CodeSOD: Don't Do This
Let's say you were writing a type checker in TypeScript. At some point, you would find that you need to iterate across various lists of things, like for example, the list of arguments to a function.Now, JavaScript (and thus TypeScript) gives you plenty of options for building the right loop for your specific problem. Or, if you look at the code our anonymous submitter sent, you could just choose the wrongest one.
Not-so-Portable Document Format
Adrian worked for a document services company. Among other things, they provided high-speed printing services to clients in the financial services industry. This means providing on site service, which is how Adrian ended up with an office in the sub-sub-basement of a finance company. Adrian's boss, Lester, was too busy "developing high-end printing solutions on a Unix system" to spend any time in that sub-sub-basement, and instead embedded himself with the client's IT team."It's important that I'm working closely with them," Lester explained, "because it's the only way we can guarantee true inter-system compatibility." With disgust, he added, "They're mostly a Windows shop, and don't understand Unix systems, which is what drives our high-speed printing solution."It was unclear to Adrian whether Lester was more interested in "working closely" or "getting access to the executive breakroom with free espressos", but that's what Lester got, while Adrian made do with a Mr. Coffee from 1987, while fielding emails from users trying to understand why their prints didn't work.Bobbi was one such user. She was fairly technical, and had prepared some complex financial reports for printing. Because she was very aware how she wanted these reports to look, she'd gone the extra step and made them as a PDF. She'd sent it over to the high-speed-printer and it got kicked back with an error about invalid files. Adrian reviewed her PDFs, couldn't see any errors or problems, tried submitting the job himself, and a few minutes later it got kicked back.Eventually, he called Lester."Hey, I've got a user trying to send some files over to the high-speed printer, and it doesn't seem like it'll take them.""Oh, is that where all these PDFs have been coming from?""Uh… yes?"Lester sighed. "See, this is why I need to be embedded with the team, they're so Windows biased, and now it's even infecting you.""Hunh?"Adrian somehow could hear Lester rolling his eyes over the phone. "The high speed printer is a Unix system, you know this.""I do know that," Adrian confirmed, still mystified."PDFs are only good for the Windows operating system," Lester said. "It's not going to print properly on a Unix operating system.""Our… high speed printer can't print PDFs?""If your users want to print PDFs, they need to print on their Windows-based printers.""I just want to confirm," Adrian said, "again, our printer can't handle PDFs, the most common print format in the world, which is 100% supported by CUPS, and probably supported directly by the printer itself?""Adrian, this is why you're down in the sub-sub-basement doing support, you have a lot to learn about cross-platform interoperability."Adrian related this information to Bobbi, and worked with her to convert the files into one of the "Unix-friendly" file formats Lester approved. After that, though, he did his own digging, and tried to understand why PDFs were forbidden.It didn't take long. Lester handled all the print jobs through a set of homebrew shell scripts. Their main job was to prepend a banner page for the print job, but they also handled details about copying files, managing the queue, and had grown into a gigantic, unmanageable mess. It wasn't that Unix couldn't print PDFs, it was that Lester couldn't hack his already hacked scripts any further to support the Portable Document Format, and thus their high-speed print system couldn't handle the standard Unix printing format of PDFs.Adrian eventually left that job. Lester, however, was still there, and so were his scripts. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
CodeSOD: Null and Terminated
There's plenty of room for debate about what specific poor choices in history lead to the most bugs today. Was it the billion dollar mistake of allowing null pointers? Is it the absolute mess that is C memory management? Or is it C-style strings and all the attendant functions and buffer-overruns they entail?A developer at Jay's company had been porting some C++ code to a new platform. That developer left, and the wheel-of-you-own-this-now spun and landed on Jay. The code was messy, but mostly functional. Jay was able to get it building, running, and then added a new feature. It was during testing that Jay noticed that some fields in the UI weren't being populated.Jay broke out a memory analyzer tool, and it popped out warnings on lines where strlcpy was being called. Now that was odd, as strlcpy is the "good" way to copy strings, with guarantees that it would never allow buffer overruns. The buffers were all correctly sized, which left Jay wondering what exactly was wrong with the calls to strlcpy?A quick grep through the code later, and Jay knew exactly what was wrong:
Error'd: The Journey is the Destination
"As if my Uber ride wasn't expensive enough on its own, apparently I have to go sightseeing East for a little while first," writes Pascal.
CodeSOD: Revenge of the Stream
It's weird to call Java's streams a "new" feature at this point, but given Java's prevalence in the "enterprise" space, it's not surprising that people are still learning how to incorporate them into their software. We've seen bad uses of streams before, notably thanks to Frenk, and his disciple Grenk.Well, one of Antonio's other co-workers "learned" their lesson from Frenk and Grenk. Well, they learned a lesson, anyway. That lesson was "don't, under any circumstances, use streams".Unfortunately, they were so against streams, they also forgot about basic things, like how lists and for-loops work, and created this:
Just Google It
Based on the glowing recommendations of a friend, Philip accepted a new job in a new city. The new city was a wonderful change of pace. The new job, on the other hand…The company was a startup, "running lean" and "making the best use of our runway". The CEO was a distant figure, but the CTO, Trey, was a much more hands on "leader". Trey was part of the interview process, and was the final decision maker for hiring Philip. On Philip's first day, Trey commented on the fact that Philip specifically hadn't gotten a degree in software engineering, but had twenty years of work experience."Honestly, that really put you over the top," Trey said. He grinned the smile of someone who has spent a lot of money engineering the perfect smile, and clapped Philip on the back. "We tend to prefer candidates from, y'know, 'non-traditional' backgrounds. I mean, I have a degree in logic!"Philip nodded awkwardly, not exactly sure what to make of that. Trey clapped him on the back again, and added. "But as you can see, I've made quite the career in tech. I think my background gives me a better perspective than someone who's been too focused on the bits and bytes, you know? Broader. Why, it's certainly helped me make connections. I know people at Google! Maybe I'll introduce you, if you promise not to go running off!" Trey laughed at his own joke.Or maybe it wasn't a joke. Philip's first few months at the company were mostly meetings. Some of those meetings were about company processes and standards, which Trey had copied from what he heard Google did. Sometimes, the meetings were more like propaganda sessions, focusing on how much this company was like Google, and would one day be as successful as Google, and how lucky you were to get in on the ground floor of the next Google.A number of the meetings focused on security, and these meetings generally had a darker, more threatening tone. "Our intellectual property," Trey explained, "belongs to our investors. We must protect it at all costs."Once Philip was properly indoctrinated into the company cult, and fully warned about security concerns, he was given access to the company's private Gitlab, hosted on the Google Cloud Platform. The first thing Philip noticed was that the installed version of Gitlab was from 2015, and there were a number of documented vulnerabilities that had since been patched in newer versions.So much for security.Their product was one gigantic Eclipse project. Emphasis on Eclipse. There were no automated builds. If you wanted to build, you used Eclipse. There were no automated deployments. If you wanted to deploy, you used Eclipse. Philip ran some automated analysis tools against the codebase, just to help him get a sense of what he was looking at.About 45% of the code was duplicated code from elsewhere in the codebase. One letter variable names were apparently the standard. There was no testing code, whatsoever. And every single third-party library was included in source control, creating a git repo that was over 2GB in size.Philip wasn't given much direction on what he should work on next. "We want to let smart people do smart things," Trey said, "like at Google. You set direction, and keep me in the loop so I can course correct."Philip decided that the first thing they needed was some automation on the builds. Then they could move up to continuous integration. It'd also be nice to get dependency management cleaned up so instead of tracking all of your dependencies in git, you could have your build/deploy system handle that."So," Philip said to Trey after explaining this, "I thought I'd get started on building with Maven. That's pretty much the standard tool for Java projects like this, I'm already familiar with it, the rest of the team is too-""I don't think that's what they use at Google," Trey said."Well, I mean…""No, no, let me make a few calls. I know people at Google."While Trey went ahead and made his calls, Philip got to work building a Maven build anyway. It turned out to be more complicated than he expected at first, especially because the code depended on some deprecated Google Cloud Platform libraries, which meant Philip had to also modernize some of that as part of the process, which meant starting on writing some unit tests to avoid introducing regressions, and it sorta turned into a yak shaving expedition."Hey," Trey said, "at Google they use Bazel, so we should use that.""Um, I mean, none of us are really familiar, and Maven is really fit for purpo-""At Google," Trey repeated, "they use Bazel."Philip and the rest of the team gave Bazel a fair shot, and spent the better part of a week trying to get their project configured in a way that worked with Bazel or configure Bazel in a way that worked with their project, and the end result was confused, angry and frustrated developers."I understand that this is what Google uses, and it might be a great fit for them, but it's really not a great fit for this project or this team," Philip explained to Trey. "I think we can get to a Maven version in just another day or two, and it'll give us all the benefits we want.""Well, I think we should do what Google does, but we have another problem," Trey said. "It seems that you merged some code to master.""Uh, yeah, just some unit tests, and the team reviewed them.""But I didn't review them," Trey said. "So I'm going to have to call a code freeze until I get a chance to understand the changes you made. No more changes until I've done that.""Do they do code freezes at Google?" Philip wondered."Of course they do."That was the last time Philip saw the CTO in person. Instead of being busy studying the code, however, Trey was busy gladhanding with investors, showing up for photo-ops with trade mags, and scheduling media appearances to talk up how this was the next Google.In the end, the code freeze lasted five months, which was longer than Philip lasted. He found another job. The startup is still running, however, but Trey is no longer the CTO. He's now the CEO, and in charge of the entire operation. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
CodeSOD: Table This for a Moment
Relational databases have very different constraints on how they structure and store data than most programming languages- tables and relationships don't map neatly to objects. They also have very different ways in which they can be altered. With software, you can just release a new version, but a database requires careful alterations lest you corrupt your data.There are many ways to try and address that mismatch in our software, but sometimes the mismatch isn't in our software, it's in our brains.Peter was going through an older database, finally migrating its schema definition into scripts that can be source-controlled. This particular database had never received any care from the database team, and instead all of the data modeling was done by developers. Developers who might not have been quite ready to design a database system from scratch.The result was this:
Demo Most Dear
Reese was driving home from work one day in 2012 when his cell phone rang out over his driving music. It wasn't a number he had stored in his contacts, but the area code and prefix were clearly from his office."Hey! This is Janet." An airy voice reverberated through his car's interior once he put the call on speaker. "I tried your extension first, but you didn't pick up. Anyway, we're waiting for you in the conference room!"Janet the PM, Reese reminded himself. Having no idea what she was talking about, he frowned at the interminable line of cars ahead of him. "What?""Initrode wants to talk about integrating with our ERP. Remember?""Yes, I know. Now?" It was past normal business hours for most of the company."I sent out a meeting invite.""I never got one.""Well, why don't you go ahead and dial into the conference call?" Janet's cheer was undiminished."I can't do this while I'm driving!" Reese protested. He glanced at the dashboard clock, at the red traffic light glowing in the distance, then sighed. "Go ahead and get started. I'm not too far away, I'll turn around and be there soon.""All right! We're in 4-B."It took Reese 20 minutes to turn around and return to the suburban office park, annoyance smoldering in his chest the whole way. In the parking lot for his building, lights were cutting on as the sun approached the horizon. He turned off the engine, took a deep breath, then exited the car to hurry off to Conference Room 4-B.While jogging through corridors and stairwells, Reese reminded himself about the potential client at hand. Initrode focused on point-of-sale systems like cash registers, and wanted help with pulling, consolidating, and reporting data from these machines on a daily basis. While the ERP offered by Reese's company wasn't state-of-the-art, it was more than qualified to handle this.Reese finally reached the conference room door and pulled it open. The other meeting participants had staked claims around a speakerphone. Their heads all swiveled to stare at him as he dropped into a seat at the far end of the table."Great, our expert just stepped in!" Janet smilingly announced for the benefit of those on the phone. "Let me introduce you to Reese, he is our expert on client/server integration. Reese, we're talking with Ed from Initrode. Ed was hoping for a little more explanation about how their systems would communicate with ours.""Sure." His heart still pounding from exertion, Reese struggled not to sound winded. "Uh, the standard way we handle integration is through a desktop client application that you would license from us and install on your machines. That application would communicate with our servers." They were working on a more modern REST interface, but as that was in its infancy, he couldn't bring it up.There was a pause on the other side. "You mentioned a license? How much would that cost?""Three thousand," Janet replied."Three thousand?""Yes."Another pause. "We were ... well, you said this application was the 'standard' method. Is there a non-standard method, then?"Janet cast a pleading look toward Reese.Reese nodded. "Well, we do have an OLE interface, but it's pretty old and unreliable. We've been phasing it out elsewhere—""How much would that cost?" Ed asked."I'm not sure," Janet replied. "I'd have to find out.""I'd also have to do checking on my end to see whether it's even feasible," Reese cautioned. "I'll need more information on your current setup."The meeting adjourned with everyone promising to forward information to everyone else. Over the next few days, Janet learned that using the OLE interface would be cheaper for Initrode, and once they heard that, that was all they cared about despite warnings of potential fragility and unreliability from Reese. Initrode then demanded an all-inclusive proof-of-concept before going forward with any formal sales or projects. This request smelled fishy to Reese, and he made his reservations known, but the powers that be insisted that he comply. Reese wound up producing a simple application in VBScript with an accompanying .NET library that did all the client/server heavy lifting. He also included a big dialog box that displayed each time the application was opened: "This is a demo application for testing purposes only."Reese sent off the demo along with all the source code. Everything went quiet for a few months. Initrode seemed to disappear off the face of the Earth ... until, of course, the demo application they'd deployed into production and trained their staff to use began breaking down.As Reese listened to Ed's frantic pleas on the phone, he had to bite his lip to keep from laughing. "I'm sorry, but that code was given to you as-is with no guarantees or support agreement. I need to escalate this to my boss."When Reese went to his boss' office and explained the situation, she let out the laugh that he'd been forced to suppress. "Now we can muscle them into an actual project!"Only that never happened. Initrode still refused to sign on the dotted line. They wanted bug fixes to the demo app, that was it. The changes they wanted were all minor tweaks they could've made themselves with the source code Reese had given them, but for some reason, they refused to touch it. Reese's initial development was billed as consulting. The frantic call from Ed was billed as consulting. Reese's bug fixes? Billed as consulting. Consulting rates were rather high, so high that it ended up costing three times as much as if Initrode had simply agreed to a project from the start.Reese eventually left to pursue new opportunities at a different company. As far as he knew, Initrode's horribly expensive demo still lived on. [Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.
Error'd: Infinite NaN
"For NaN easy payments of infinity dollars per month, this too can be YOURS!" Daniel B. writes.
Failing the Test
Like many dev teams, Rubi's team relies heavily on continuous integration. Their setup, like many others, relies on git hooks, and whenever someone pushes a commit to any branch, it automatically runs all the associated unit tests. Good code stays green, and any bugs are immediately revealed. Branches with failing tests cannot be merged into the main branch, which is all pretty reasonable.Recently, Ruby pushed a commit on a branch up, and pretty much immediately realized that the tests were going to fail because she forgot to update a related code file. Even as she started to amend the commit, she waited for the CI server to cough up an error. And waited. And waited. And waited.Now, for this particular repository, Rubi wasn't usually doing much development in it. She was helping with a big system upgrade, and so her first thought was that she must have made some other mistake. After all, it's not like automated CI would just get turned off, right?Well, when she glanced at the YAML file which controlled their test runner:
Go Forth, Young Programmer
The past is another planet, but a familiar one. Back in the far off year of 1989, Rick Poleshuck took a job with a company that made a computer product for nurses's stations in hospitals. Now, this product was for notes, and it was an "all inclusive" product- software, proprietary hardware, networking, terminals, everything. And it was written in Forth.Now, this is what we might call a "classic Forth" system, and in such a system, Forth ran on bare metal. No OS, no filesystem, and a simple scheduler. This was also the system they developed on: the source just lived in raw 1KB blocks on the hard disk, and they edited blocks directly. That's not a WTF, that's just how things were done in that environment.While this software didn't have any safety implications, it was used in the medical field, so "strict adherence to coding standards" was required. Unfortunately, the coding standard was written by someone with strong opinions, but not a great deal of common sense.For example, the standard distinguished between code blocks and comment blocks. Each 1KB code block also had a 1KB comment block associated with it. Documentation about what the code block did went in the comment block. No comments went in the code block. In fact, nothing but code went in the code block- and that included indentation. Each code block was essentially supposed to be one extremely long line of Forth code.The standards made sure developers avoided wasteful and dangerous habits, like documenting their code, but it was silent about some other potentially bad habits. In Forth, for example, nested loops can jump up the hierarchy of loops- the innermost can just jump straight back to the outermost. There are good language reasons for why that's allowed in Forth, but it's the sort of thing that can make your code much harder to understand and harder to debug. So of course, the network stack Rick had to work with used a lot of that convention.Speaking of unusual conventions, anyone who's done some low-level C programming or looked at OS or driver code, may have seen cases where Assembly gets mixed in with C. Rick's employer took that a step farther- they mixed machine code in with their Forth. "For example," Rick writes, "0x90 is a NOP instruction on the 80286 CPU that was used." It's important to remember that they weren't allowed- by coding standards, not technology- to use any in-line comments in their code blocks, which meant these blobs of machine code were just long strings of hex numbers, with no explanation of what they were doing.All of these conventions made everyone's lives harder, made the code harder to reason about, but were enforced with an iron fist by the various team leads and management. As different as the real-world constraints of programming Forth in 1989 were, it seems there are certain constants which always follow us: bad policies, enforced for the sake of enforcing them.Rick has one last thing to add about their process, this time on what they did for source control:
Version Chaos
Today's submitter, Erica, writes: Every time I tell this story to other developers they don't believe it, because this is quite possibly the dumbest way version control has ever been done.When Erica joined Initech's mobile team, she came in as a mid-level developer on a team with one senior (Steve) and two interns (Dan and Trevor). Steve wasn't dedicated to the project; in fact, he was 80% on a more important team, so he barely had time for leading the mobile team. It fell to the project manager (Benjamin) to be the technical lead on the project as well as managing the interns. To be fair, this project was mostly meant as a training exercise, something low priority and safe for interns to cut their teeth on. So far, so good.The app was for Android, and they were using the Flutter SDK, which was at the time on version 0.something and used by almost nobody in the industry—Benjamin's idea. The build was buggy and returned such unhelpful errors that Benjamin couldn't build it on his machine, which was standing in for a CI/CD machine to produce the integrated dev build they were meant to hand off to QA for testing. Rather than taking the chance to teach interns best practices on how to write good code, Benjamin banned code reviews, seeming to believe that any code that ran was good code. Erica's objections fell on deaf ears. She was a girl, what did she know about code? Any time she had a point, such as "Let's not run an entire ecommerce database on a single table", she had to get Dan to say it for her for Benjamin to even halfway consider it.But none of that is the point of today's story. The true horror of the project lay not in the code quality, but in the version control practices—and I mean both "version control" and "practices" in the loosest sense of the words. Each developer had a branch to work on. Other than Erica, nobody seemed to ever merge master back into their branch. Instead, Benjamin had them each make a pull request at the end of the day into master, and that was the only direction code flowed. So, as you might expect, the branches varied widely within a week or two of this practice.First thing in the morning, Benjamin would call a team meeting and merge the open pull requests. How would he know which line to take? He'd just ask the developer which line, and take that entire line. As you can imagine, master quickly became an unreadable mess, which is why Benjamin couldn't build from it. Half the time, it wouldn't compile. Erica would merge master into her branch, then spend 2 hours trying to fix everything so it worked, then push her version upstream so Dan could work from her branch. Trevor didn't even bother with her branch, focusing on his own instead, meaning code that worked on his machine bore no resemblance to the code on Erica's. He didn't know any better; he was listening to Benjamin, who was meant to be in charge of the interns.Sometimes, however, perseverance wins the day. Erica outlived Benjamin on the project, as he finally got moved to something bigger and client-focused. That left her in charge of the interns, with plenty of time to teach them that everything they had learned thus far was wrong. [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
Tales from the Interview: The Whiteboard Challenge
Like many of us, Igor F keeps his LinkedIn profile vaguely up to date with his career, and that means he inevitably gets messages from recruiters trying to find talent for the latest trendy startup, or the big stable company struggling to find developers happy to work in its code mines, or the contracting company trying to staff up.Igor usually ignored the pitch, but one recruiter said they were representing a startup in a domain that Igor was really interested in, and was hinting that they had money to burn.The few message exchanges turned into a phone call. "So, your background is exactly what my client is looking for," the recruiter explained. "Like, literally, your resume is basically the job posting, to a 'T'. I've worked with these folks for a while, and I'm getting the sense that you would get along great with them.""I mean," Igor said, "I'd like to, but it's probably too early to say that.""Sure, sure," the recruiter said. "But that's why I want to get you on the phone with them. Their senior principal engineer is ready to have a conversation whenever you are."Igor nodded along, used to hearing pitches like this. "Well," he said, "I'm not precisely looking for a new job, I've got room to grow in this position-""Not like they can give you at Initech. And speaking of growth, let me tell you what their salary range is."The recruiter said what the salary range was. It was significantly higher than what Igor was making now. Not quite double, but close enough to make the difference academic. With that kind of money flying around, Igor couldn't say no to an interview.A few days later, Igor, the recruiter, and Dudley, the "senior principal engineer" got together for a call. They went through the usual interview song and dance, and eventually Dudley got to the inevitable programming questions."Could you," he said, with a long pause to make it sound like he was thinking up the question on the spot, "oh, I don't know, write me code that'll traverse a tree.""Yes," Igor said. He waited to hear if they were going to pull up a screen sharing session, or he was going to do a take-home assignment, or what was actually about to happen.He waited longer.The silence stretched out to the point where it went from merely uncomfortable to agonizing."So," Dudley said, "go ahead.""Like, now?""Yes, just tell me the code that you'd write.""You mean, just over the phone?""Yes," Dudley said, as if that should be perfectly obvious. "Think of it light a whiteboard challenge.""But… I don't have a whiteboard. And even if I did, you couldn't see it.""Think of me as your whiteboard," Dudley said. He didn't say, "you idiot," but his tone implied it."Okay, so you'd have a function that takes a node as a parameter," Igor started explaining the pseudocode logic that he'd use.Dudley interrupted. "How do you define that function? This is a coding challenge."Igor looked at his phone, wondering if he should just hang up, or give it the old college try, or just truck on with the pseudocode explanation. "Uh… let's say for this it could be public, static, traversetree, with node as a parameter."Dudley huffed. "Don't you mean 'parenthesis, Node n, close parenthesis, open curly bracket? This is a coding challenge."Igor did his best to verbally type out the Java syntax for a depth-first tree traversal. Each time he didn't specify a bracket, or a semi-colon, or a parenthesis, Dudley was ready to point out his mistake. Even pulling up a text editor so that he could type along didn't exactly make it easy to symbol-by-symbol "type" code over the phone.The interview ended the way all awkward interviews do, with some mumbled "thanks for your time," and a hasty end to the call. Igor never heard back about the job, or from the recruiter. But it was definitely clear that he hadn't gotten "along great" with anyone on that call. [Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.
Error'd: Something or Nothing at All
"I didn't know that I could buy an empty shopping cart from name.com, but here I am," Tom writes.
CodeSOD: A Match Made In…
Andy C writes:
CodeSOD: Callback Bondage
"Garbage collected languages can't have memory leaks," is well established as a myth, but we still have plenty of code which refuses to clean up after itself properly.An anonymous submitter was working with a single-page-app front-end which wraps a stream abstraction around a websocket. Messages arrive on the stream, and callbacks get invoked. When certain parameters change, new callbacks need to be registered to handle the new behavior. The old callbacks need to be unbound- and it's that step this code doesn't do.
...16171819202122232425...