-Поиск по дневнику

Поиск сообщений в rss_thedaily_wtf

 -Подписка по e-mail

 

 -Постоянные читатели

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 06.04.2008
Записей:
Комментариев:
Написано: 0

The Daily WTF





Curious Perversions in Information Technology


Добавить любой RSS - источник (включая журнал LiveJournal) в свою ленту друзей вы можете на странице синдикации.

Исходная информация - http://thedailywtf.com/.
Данный дневник сформирован из открытого RSS-источника по адресу http://syndication.thedailywtf.com/thedailywtf, и дополняется в соответствии с дополнением данного источника. Он может не соответствовать содержимому оригинальной страницы. Трансляция создана автоматически по запросу читателей этой RSS ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

[Обновить трансляцию]

Go Forth, Young Programmer

Среда, 20 Января 2021 г. 09:30 + в цитатник

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:

And finally source control was a single master printed copy of the code and a saved 1/2 height 5 1/4" hard disk for each major release.

[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.

https://thedailywtf.com/articles/go-forth-young-programmer


Метки:  

Version Chaos

Вторник, 19 Января 2021 г. 09:30 + в цитатник

Tangled power lines in Puerto Rico

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!

https://thedailywtf.com/articles/version-chaos


Метки:  

Tales from the Interview: The Whiteboard Challenge

Понедельник, 18 Января 2021 г. 09:30 + в цитатник

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.

https://thedailywtf.com/articles/the-whiteboard-challenge


Метки:  

Error'd: Something or Nothing at All

Пятница, 15 Января 2021 г. 09:30 + в цитатник

"I didn't know that I could buy an empty shopping cart from name.com, but here I am," Tom writes.

 

Calvin K. writes, "Samsung is really confused here...Samsng is really confused here....

 

"I think I'll get a big raise if I can get the DO NOT ISSUE certification." wrote Thomas J.

 

David B. wrote, "After my payment info, they seem to think I still owe them, just not very much."

 

"Just did an induction questionnaire for a venue. Usually these things are annual, looks like I hit the jackpot on this one!" Justin R. wrote.

 

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

https://thedailywtf.com/articles/something-or-nothing-at-all


Метки:  

CodeSOD: A Match Made In…

Четверг, 14 Января 2021 г. 09:30 + в цитатник

Andy C writes:

One of our colleagues dug this code up from an outsourced project. Took a few us to try to find out what it actually does, we're still not completely sure.

This is the associated Java code:

if (productList != null && !productList.isEmpty()) { for (int i = 0; i < productList.size(); i++) { String currentProductID = String.valueOf(productList.get(i).getProductId()); String toMatchProductID = String.valueOf(currentProductID); if (currentProductID.equals(toMatchProductID)) { productName = productList.get(i).getProductName(); break; } } }

If you just skim over the code, something you might do if you were just going through a large codebase, it looks like a reasonable "search" method. Find the object with the matching ID. But that's only on a skim. If you actually read the code, well…

First, we start with a check- make sure we actually have a productList. The null check is reasonable (I'll assume this predates Java's Optional type), but the isEmpty check is arguably superfluous, since we enter a for-loop based on size()- an empty list would just bypass the for loop. Still, that's all harmless.

In the loop, we grab the current item (item 0, on the first iteration), and that's our currentProductID. We choose to cast it into a string, which may or may not be a reasonable choice, depending on how we represent IDs. Since this is imitating a search method, we also need a toMatchProductID… which we make by cloning the currentProductID.

If the currentProductID equals the toMatchProductID, which it definitely will, we'll fetch the product name and then exit the loop.

So, what this method actually does is pretty simple: it gets the productName of the first item in the productList, if there are any items in that productList. The real question is: how did this happen? Was this a case of copy/paste coding gone wrong? Purposeful obfuscation by the outsourcing team? Just a complete misunderstanding of the requirements corrected through quick hacking without actually fixing the code? Some combination of all three?

We know what the code does. What the people writing it do, that we're definitely not sure about.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

https://thedailywtf.com/articles/a-match-made-in


Метки:  

CodeSOD: Callback Bondage

Среда, 13 Января 2021 г. 09:30 + в цитатник

"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.

const channelName = this.channel.name; this.channel.bind('updated', (data) => { if (this.channel.name === channelName) { this.updateData(data) } });

The bind method attaches a new callback to a given channel. Without a matching unbind to remove the old callback, the old callback will sit in memory, and keep getting invoked even as it does nothing useful. Over time, this leads to performance issues.

Or, at least, it could lead to performance issues. The original developer had a… special solution to handling garbage collection. I'll let our submitter explain:

On the plus side, their cleanup logic for the component that uses this data unsubscribes all open websocket channels across the entire app on unmount, including channels owned by unrelated components, so we can rest assured that eventually they'll definitely be gone. Along with everything else.

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

https://thedailywtf.com/articles/callback-bondage


Метки:  

CodeSOD: Put in Order

Вторник, 12 Января 2021 г. 09:30 + в цитатник

Rust is one of the "cool" languages these days. It promises all the low-level power of C with memory safety and "modern" programming conventions like iterables and maps. High performance, expressive language, low-level power seems like a great combination for certain domains.

Now, Jenna Winchester needed to do some Morton Coding or Z-indexing, which is an algorithm which lets you take multidimensional points and turn them into 1-dimensional points in a way that maintains their spatial relationships- essentially a fast way of traversing a quadtree. It's a fairly simple and fast algorithm, especially if you implement it using bitwise operations. A naive implementation, without optimizations, can do its job with very few CPU cycles, relatively speaking.

And while Jenna could have implemented her own version of it, never reinvent a wheel that someone else probably has. So she tracked down a Rust library (or crate, if we're using Rust terminology) which promised to do the job. Jenna's expectation was that she could feed in her 5-dimensional point, and get back the z-index by simply doing something like let output = input.z_index(). Let's call the library morty_code, because we should focus more on the painful experience of working with a badly designed API than worry about calling out a library for a mildly niche language for a very specific problem domain.

That, of course, would be too easy. The code which Jenna needed to write to perform the core purpose of what the library claimed to do was this:

fn morton_encode_u8_5d_zdex (input: [u8; 5]) -> u64 { use zorder::*; let usize_bits = 8*core::mem::size_of::<usize>(); let transmute_input = |x: &u8| -> FromU8 {(*x).into()}; input // Take the original input, .iter() // element by element... .map(transmute_input) // Transform each to the custom input types zindex needs... .z_index() // Compute the result... .unwrap() // Panic if there's an error... (Can there be one? Who knows!) .iter_storage() // Take the result usize by usize... .fold(0 as u64, |acc, a| (acc<as u64) // ...and finally, unify the iterator of usizes into a single u64. // Can you just FEEL the ergonomics? }

Now, even if you don't know Rust, which I don't, this looks menacing, even before you read Jenna's comments. Here's the key things: you can compute the Z-index using bitwise operations. The library author, however, didn't understand this, or didn't care, so instead used a different datastructure: a vector of bits. The line where we define transmute_input invokes FromU8, which takes an 8-bit number and turns it into an 8-item vector of bits. Which, despite knowing that it will always need exactly 8 items to hold 8 bits, the actual implementation of FromU8 dynamically allocates that memory.

So, with that in mind, we can trace through the implementation. We take our 5-dimensions of 8-bit integers as input. We iterate across each one, converting each to a vector-of-bits using .map(transmute_input), for each dimension, we can then calculate the z_index(), which comes back as a vector-of-bits, so we have to unwrap() it. We chunk the results back up using that iter_storage() and then finally we can reduce the z-indexes for each dimension using fold to bitshift them around.

If that seems like a lot of work to implement a simple algorithm first described in the 1960s, you'd be right. Jenna ran some performance tests comparing her naive implementation with the implementation from this library:

I checked the assembly that's emitted for a simple case of two u32s to one u64. A very naive version needed 600 machine instructions. morty_code needed more than three thousand. And since it contains multiple subroutines, morty_code turns out to be two orders of magnitude slower than the naive version.

But hey, we wouldn't want to use the naive version, because we'd have to worry about things like edge cases and faulty assumptions which surely means the library has to be more correct, right?

I whipped up a couple simple tests to ensure that the functions operate correctly. Surprise! The morty_code version doesn't. It ends up putting the high-significance bits at the end and the low-significance bits at the beginning. Printing the vector-of-bits directly shows the result correctly, but printing it after transforming it into a u64 shows the bits reversed.

Which is to say that the internal representation surprises you with its endianess. I suspect that it was that endian problem which initially lead to the creation of the vector-of-bits type that's used internally, but there are far easier ways to resolve conflicts with byte order.

Jenna contacted the original developer of the library, hoping to maybe help improve the experience for other developers.

This was the point at which I decided that the code has absolutely no redeeming features. A few fruitless posts of dialogue later, I realised that talking to TDWTF would be much more productive than talking to the maintainer. So... here we are.

Here we are, but where is "here" on the z-order curve?

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

https://thedailywtf.com/articles/put-in-order


Метки:  

It's a Gift

Понедельник, 11 Января 2021 г. 09:30 + в цитатник

Tyra was standing around the coffee maker with her co-workers when their phones all dinged with an email from management.

Edgar is no longer employed at Initech. If you see him on the property, for any reason, please alert security.

"Well, that's about time," Tyra said.

They had all been expecting an email like that. Edgar had been having serious conflicts with management. The team had been expanding recently, and along with the expansion, new processes and new tooling were coming online. Edgar hated that. He hated having new co-workers who didn't know the codebase as intimately as he did. "My technical knowledge is a gift!" He hated that they were moving to a CI pipeline that had more signoffs and removed his control over development. "My ability to react quickly to needed changes is a gift!" He hated that management- and fellow developers- were requesting more code coverage in their tests. "I write good code the first time, because I've got a gift for programming!"

These conflicts escalated, never quite to screaming, but voices were definitely raised. "You're all getting in the way," was a common refrain from Edgar, whether it was to his new peers or to management or to the janitor who was taking too long to clean the restroom. It seemed like everyone knew Edgar was going to get fired but Edgar.

Six months later, the team was humming along nicely. Pretty much no one thought about Edgar, except maybe to regale newbies with a tale of the co-worker from hell. One day, Tyra finished a requirement, ensured all the tests were green in their CI server, and then submitted a pull request. One of her peers reviewed the request, merged it, and pushed it along to their CD pipeline.

Fortunately for them, part of the CD step was to run the tests again; one of the tests failed. The failing test was not anything related to any of the changes in Tyra's PR. In fact, the previous commit passed the unit test fine, and the two versions were exactly the same in source control.

Tyra and her peers dug in, trying to see what might have changed in the CD environment, or what was maybe wrong about the test. Before long, they were digging through the CD pipeline scripts themselves. They hadn't been modified in months, but was there maybe a bad assumption somewhere? Something time based?

No. As it turned out, after many, many hours of debugging, there was an "extra" few lines in one of the shell scripts. It would randomly select one of the Python files in the commit, and a small percentage of the time, it would choose a random line in the file, and on that line replace the spaces with tabs. Since whitespace is syntactically significant in Python that created output which failed with an IndentationError.

A quick blame confirmed that Edgar had left them that little gift. As for how it had gone unnoticed for so long? Well, for starters, he had left during that awkward transition period when they were migrating new tools. The standard code-review/peer-review processes weren't fully settled, so he was able to sneak in the commit. The probability that it would tamper with a file was very low, and it wouldn't repeat itself on the next build.

It was hard to say how many times this had caused a problem. If a developer saw the unit test fail after accepting the PR, they may have just triggered a fresh build manually. But, more menacing, they didn't have 100% unit test coverage, and there were some older Python files (mostly written by Edgar) which had no unit tests at all. How many times might they have pushed broken files to production, only to have mysterious failures?

In the end, Edgar's last "gift" to the team was the need to audit their entire CI/CD pipeline to see if he left any more little "surprises".

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

https://thedailywtf.com/articles/it-s-a-gift


Метки:  

Error'd: Nope, that was Prod

Пятница, 08 Января 2021 г. 09:30 + в цитатник

"They say you shouldn't test in prod... They aren't wrong." Dave P. writes.

 

Dave W. wrote, "I guess even the USPS's 'missing mail' site is missing in action."

 

"$69.99 instead of $69.99...Thank you, Microsoft?" writes Carlos.

 

Pascal wrote, "Looks like the test was more successful than they had planned."

 

"Looks like eBay is keeping it as simple as possible," Peter K. writes.

 

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

https://thedailywtf.com/articles/nope-that-was-prod


Метки:  

Going Backwards

Четверг, 07 Января 2021 г. 09:30 + в цитатник

Nearly 15 years ago, fresh out of college, Giuseppe was hired on at a mobile networking company. The company wasn't a software company, but since they were heavy in networking and could handle all sorts of weird technical problems there, software must basically be the same thing, so they also started producing applications to manage those networks.

It didn't take them long to discover that "building networks" and "writing software" are different skillsets, and so they did what every company with some room in the budget does: they hire a pack of Highly Paid Consultants to get their project on track.

Giuseppe joined the team just as the budget for consultants ran out. They "knowledge transfered" "everything" in a whirlwind of incomprehensible PowerPoint presentations, and then vanished back into whatever lairs HPCs come from, and left Giuseppe and the other new hires to figure out what was going on.

When the HPCs were hired, the company had extensively specified the requirements. Each requirement was expressed in terms like:

  • 12.2.23.a.1 The user will be able to reverse their journey through the app using the back button.
  • 12.2.23.a.2 The app will remember the last 5 screens the user has visited.

There was an elaborate tracking system, with multiple signoffs, to confirm who tested what and when. That specific requirement, 12.2.23.a.2, was signed as "passed" by the original HPC. Then it was passed off to a QA test, which also signed off. Then it went to the users, who submitted a defect: the back button often doesn't behave as expected. It drifted back to the original developer, who closed the defect as "can not replicate", QA signed off again, the user re-opened the ticket claiming the issue was still there, and round and round until the budget for consulting ran out and it was Giuseppe's turn to figure out what was actually going on.

There was no automated testing, and no formal test plan, but it didn't take Giuseppe long to figure out what the bug was. In fact, it took slightly more than 6 navigation actions, to discover that he could replicate the bug consistently. It also explained why the HPC couldn't replicate the bug: they navigated through exactly six pages, and confirmed that if they hit the back button 5 times, they got the same pages they'd been through. If they'd gone to one more page, they would have seen that it didn't work. And the offending code was easy to spot:

private void OnPageNavigated(Page pageFrom) { if(m_backStack.Count < 5) { m_backStack.Push(pageFrom); } }

Instead of tracking the last five pages the user viewed, this tracked the first five pages they viewed, and ignored every navigation thereafter.

This was just one of many bugs around the back button alone, and additional confusion about the specs. Many pages might open a modal dialog- should that be in the history? If it is, does it count against the 5 pages total? It ended up creating situations where the stack of navigation events needed to track more than 5 items, because of the fuzzy definition of what was a "page", but that created additional bugs because if you could navigate backwards more than five times, you were technically in violation of the spec.

Giuseppe adds:

As I've moved up the software engineering ladder I cringe about how the project was run and managed. Things like unit testing or CI didnt exist, all testing was extremely manual, performed by a dedicated team of 3 testers to an exhaustive specification. … As a [junior] developer nobody ever performed a code review on what I wrote, it went straight into the app. In the whole time I worked there only one person gave me feedback on my code when I screwed up OTA updates that amounted to 'dont do it again'. I was there for over 2 years, and it should be no surprise that the product still hadn't been signed off when I left.

It wasn't signed off when he left, and it probably hasn't been signed off to this day.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

https://thedailywtf.com/articles/going-backwards


Метки:  

CodeSOD: Copy Paste Paste Paste Paste

Среда, 06 Января 2021 г. 09:30 + в цитатник

"Hey," someone on Russell F's team said. "We should add some keyboard navigation to our web app." That struck everyone as an "easy win", specifically because they were really talking about making "enter" and "escape" do something useful.

They wrote some quick requirements, passed it off, and the developer submitted a surprisingly long pull request. Russell passed a sample of three out of the dozens of methods:

function lr_control(event) { var current = document.getElementById('lr'); var next = document.getElementById('rf'); var back = document.getElementById('lf'); if (event.key == "Enter") { divareInoperativeSensorsReplacedShow(); } if (event.key == "Escape") { unCheck(current); } nav_control_clickable(current, next, back, event); return; } function rf_control(event) { var current = document.getElementById('rf'); var next = document.getElementById('rr'); var back = document.getElementById('lr'); if (event.key == "Enter") { divareInoperativeSensorsReplacedShow(); } if (event.key == "Escape") { unCheck(current); } nav_control_clickable(current, next, back, event); return; } function rr_control(event) { var current = document.getElementById('rr'); var next = document.getElementById('yesReplace'); var back = document.getElementById('rf'); if (event.key == "Enter") { divareInoperativeSensorsReplacedShow(); } if (event.key == "Escape") { unCheck(current); } nav_control_clickable(current, next, back, event); return; }

At no point did the similarity between all these methods ever make the developer responsible think, "oh, there's gotta be an easier way." No, they just copied and pasted, again and again, changing only the document elements that they point at.

Russell supplied some comments on the request, and pointers on how to streamline this code.

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

https://thedailywtf.com/articles/copy-paste-paste-paste-paste


Метки:  

The Contract Position

Вторник, 05 Января 2021 г. 09:30 + в цитатник

Mandi didn't plan to take a staff job at a university. To the contrary, she'd heard some bad things: loads of office politics, budgets so thin you need quantum mechanics to describe their position, and bureaucracy thick enough to drown any project.

But one day, she met her old colleague Scot for lunch, and they got to chatting about his university job. "Oh, yeah, that's common enough," he said, "which is why my team isn't structured that way. We're doing in-house development of educational solutions, which is a fancy way of saying 'nobody understands what we do, so they leave us alone'."

Scot invited her to take a tour of his office, meet some of his co-workers, talk a little about the work they were doing. They were based in a rented office just at the edge of campus, sharing the floor with a few scrappy startups. It wasn't a fancy space, and it was a little cramped, but the first and last thing Mandi noticed was how happy everyone was to be there.

Augusta, the front-end lead, talked a little about their framework selection process, and how they made their choices, not based on what was new and trendy, but based on what felt like a really good fit for their subject matter. Harry, who handled the middleware, was happy to explain how he'd needed some time to get up to speed on the right cloud scaling options, but the team was there to support him, and they eventually got a great set of automation built which handled spikes but kept costs down. Quinn rhapsodized about how great it was to work closely with the end users, to really build the solution that worked best for them, and how exciting it was to see their requirements translate into implemented software with tangible benefits.

Unlike pretty much any place Mandi had ever seen, everyone was happy to be there. Everyone liked the work they were doing. Everyone felt empowered to make the best choices, to work through challenges with the rest of the team, and everyone enjoyed celebrating their successes together.

"I always have to bring people in," Scot said, "because nobody believes me when I tell them about how great my job is."

"Honestly, I still don't believe it," Mandi said.

"Well, I did have a bit of an ulterior motive. We're looking to scale up the team a bit, which means I'll have a position soon. It'll take a little bit to grind those gears- that has to go through the university hiring process, but I hope you apply. I think you'd be a great fit."

Mandi did apply, when the position finally opened up. It was a slow-moving interview process, mostly through the university HR department, but she met Scot one more time, early in the process. Then, she landed the job, a contract-to-hire position.

At that point, Scot didn't work there anymore. He had resigned, and since the team was actively working, and since the HR process was painfully slow, the HR department didn't hire a replacement as an employee- they hired a contractor. Technically, Mandi worked under the same contract, and thus her direct manager was Cyril, the new team lead.

There was just one problem with that: by both university policy and IRS rules, contract employees can't manage regular employees. So Cyril's title was just "scrum master", and he technically had no management authority. Which meant the regular employees ignored him.

Mandi and one other contractor reported to Cyril, but nobody else did.

The overall project lead, Ruthie, was also a contractor, but hired through a different contracting firm. Not only did she have no authority over regular employees, she had no authority over any other contractors. Nobody reported to her, but she was in a management role.

The result of this management omni-shambles was meetings. Loads of meetings. Daily standups became daily "take a load off, we'll be here awhiles". After the standup, Cyril would be pulled into meeting after meeting as every section of the department started pulling in different directions, so despite being the "scrum master", he had no idea what anyone on the team was doing. Ruthie threw meetings on everyone's calendar, which nobody attended, because nobody worked for Ruthie. The only way for a contractor to get a regular employee's attention was to schedule a meeting.

Above both Ruthie and Cyril was the technical lead for the entire campus IT department. He was the only person in the org chart that everyone technically reported to, but he had never been a fan of the entire "rent an off campus office and let smart people solve problems," approach. While he was the only one who could potentially set some direction, he had no interest in doing so. The one time Mandi was on a conference call with him, he excused himself, "This isn't really a priority for me right now, I have other issues I need to address that are more important."

Mandi stuck it out until the end of her contract period. She never received an offer for a full-time position, and frankly, she wouldn't have taken it anyway. Her fellow subcontractor, the only other person who reported to Cyril, did. So his HR hiring process can work, eventually, for some people.

[Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!

https://thedailywtf.com/articles/the-contract-position


Метки:  

CodeSOD: Generated Requests

Понедельник, 04 Января 2021 г. 09:30 + в цитатник

If you've worked with developing software of any real complexity, you've probably come across a library or tool that does code generation. Instead of writing all the boring boiler-plate stuff yourself, you maybe throw a little configuration at the system and let it generate all those classes for you. I'd argue that, in most cases, that sort of thing is a code smell- it's not in and of itself bad, but it hints as missed abstractions. There's probably a general way to represent what you want to represent without generating a big pile of classes. The question is: is the additional abstraction worth it, or should you just generate code to get it done?

Russell was recently browsing the documentation for Amazon Web Services. The Java SDK allows you to send requests to AWS to automate things in their cloud. When you send a request, you need an AmazonWebServiceRequest object. Now, AmazonWebServiceRequest is itself an abstract class, so we need to send a concrete implementation, specific to the operation we want to perform. That means it's going to be one of:

AbortDocumentVersionUploadRequest, AbortEnvironmentUpdateRequest, AbortMultipartUploadRequest, AbortMultipartUploadRequest, AbortVaultLockRequest, AbstractPutObjectRequest, AcceptCertificateTransferRequest, AcceptDirectConnectGatewayAssociationProposalRequest, AcceptDomainTransferFromAnotherAwsAccountRequest, AcceptGrantRequest, AcceptHandshakeRequest, AcceptInboundCrossClusterSearchConnectionRequest, AcceptInputDeviceTransferRequest, AcceptInvitationRequest, … VerifySoftwareTokenRequest, VerifyTrustRequest, VerifyUserAttributeRequest, ViewBillingRequest, VoteOnProposalRequest, WithdrawByoipCidrRequest, WithdrawByoipCidrRequest, WriteRecordsRequest

I skipped a… few thousand of them in the middle there. You can get them all on the docs page. If you dig into any of the concrete implementations, they're all tagged as @Generated. I'm sure that there are more convenient methods which wrap around this, and that your average SDK user is never going to need to directly interact with any of these classes, but when you see a wall of generated classes, you can't help but wonder if this is the best approach. At a certain level, SDKs are meant to be understood by humans, and if you have about 9,000 auto-generated types, maybe you've lost the plot just a little bit.

And if you're worried about how you handle the response, don't be. Each of these request classes has a Result version as well. Well, not each of them- there's only 8,704 Result types. Now that's efficient.

[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.

https://thedailywtf.com/articles/generated-requests


Метки:  

Error'd: Winter ...Delivered!

Пятница, 01 Января 2021 г. 09:30 + в цитатник

"I wanted to find out how much snow Providence got overnight and apparently, Amazon wants to sell me some of it," Francis B. writes.

 

John C. wrote, "Yes, Windstream, I have both questions and feedback on this."

 

"Well, I mean, both haggis and nappies are kind of intestine related," writes Andy.

 

Robert F. writes, "My propane tank is full of 84E84b089... Are you sure that's not my septic tank?"

 

"In an attempt to connect with more voters, it looks like Trump is growing a placeholder moustache," wrote Hugh S.

 

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

https://thedailywtf.com/articles/winter-delivered


Метки:  

Best of…: Best of 2020: Web Server Installation

Четверг, 31 Декабря 2020 г. 09:30 + в цитатник
While this year has felt endless, there are projects which will feel like they take forever. As we wrap up our tour of the best of 2020, let's visit an endless project. Original -- Remy

Connect the dots puzzle

Once upon a time, there lived a man named Eric. Eric was a programmer working for the online development team of a company called The Company. The Company produced Media; their headquarters were located on The Continent where Eric happily resided. Life was simple. Straightforward. Uncomplicated. Until one fateful day, The Company decided to outsource their infrastructure to The Service Provider on Another Continent for a series of complicated reasons that ultimately benefited The Budget.

Part of Eric's job was to set up web servers for clients so that they could migrate their websites to The Platform. Previously, Eric would have provisioned the hardware himself. Under the new rules, however, he had to request that The Service Provider do the heavy lifting instead.

On Day 0 of our story, Eric received a server request from Isaac, a representative of The Client. On Day 1, Eric asked for the specifications for said server, which were delivered on Day 2. Day 2 being just before a long weekend, it was Day 6 before the specs were delivered to The Service Provider. The contact at The Service Provider, Thomas, asked if there was a deadline for this migration. Eric replied with the hard cutover date almost two months hence.

This, of course, would prove to be a fatal mistake. The following story is true; only the names have been changed to protect the guilty. (You might want some required listening for this ... )

Day 6

  • Thomas delivers the specifications to a coworker, Ayush, without requesting a GUI.
  • Ayush declares that the servers will be ready in a week.

Day 7

  • Eric informs The Client that the servers will be delivered by Day 16, so installations could get started by Day 21 at the latest.
  • Ayush asks if The Company wants a GUI.

Day 8

  • Eric replies no.

Day 9

  • Another representative of The Service Provider, Vijay, informs Eric that the file systems were not configured according to Eric's request.
  • Eric replies with a request to configure the file systems according to the specification.
  • Vijay replies with a request for a virtual meeting.
  • Ayush tells Vijay to configure the system according to the specification.

Day 16

  • The initial delivery date comes and goes without further word. Eric's emails are met with tumbleweeds. He informs The Client that they should be ready to install by Day 26.

Day 19

  • Ayush asks if any ports other than 22 are needed.
  • Eric asks if the servers are ready to be delivered.
  • Ayush replies that if port 22 needs to be opened, that will require approval from Eric's boss, Jack.

Day 20

  • Ayush delivers the server names to Eric as an FYI.

Day 22

  • Thomas asks Eric if there's been any progress, then asks Ayush to schedule a meeting to discuss between the three of them.

Day 23

  • Eric asks for the login credentials to the aforementioned server, as they were never provided.
  • Vijay replies with the root credentials in a plaintext email.
  • Eric logs in and asks for some network configuration changes to allow admin access from The Client's network.
  • Mehul, yet another person at The Service Provider, asks for the configuration change request to be delivered via Excel spreadsheet.
  • Eric tells The Client that Day 26 is unlikely, but they should probably be ready by end of Day 28, still well before the hard deadline of Day 60.

Day 28

  • The Client reminds Eric that they're decommissioning the old datacenter on Day 60 and would very much like to have their website moved by then.
  • Eric tells Mehul that the Excel spreadsheet requires information he doesn't have. Could he make the changes?
  • Thomas asks Mehul and Ayush if things are progressing. Mehul replies that he doesn't have the source IP (which was already sent). Thomas asks whom they're waiting for. Mehul replies and claims that Eric requested access from the public Internet.
  • Mehul escalates to Jack.
  • Thomas reminds Ayush and Mehul that if their work is pending some data, they should work toward getting that obstacle solved.

Day 29

  • Eric, reading the exchange from the evening before, begins to question his sanity as he forwards the original email back over, along with all the data they requested.

Day 30

  • Mehul replies that access has been granted.

Day 33

  • Eric discovers he can't access the machine from inside The Client's network, and requests opening access again.
  • Mehul suggests trying from the Internet, claiming that the connection is blocked by The Client's firewall.
  • Eric replies that The Client's datacenter cannot access the Internet, and that the firewall is configured properly.
  • Jack adds more explicit instructions for Mehul as to exactly how to investigate the network problem.

Day 35

  • Mehul asks Eric to try again.

Day 36

  • It still doesn't work.
  • Mehul replies with instructions to use specific private IPs. Eric responds that he is doing just that.
  • Ayush asks if the problem is fixed.
  • Eric reminds Thomas that time is running out.
  • Thomas replies that the firewall setting changes must have been stepped on by changes on The Service Provider's side, and he is escalating the issue.

Day 37

  • Mehul instructs Eric to try again.

Day 40

  • It still doesn't work.

Day 41

  • Mehul asks Eric to try again, as he has personally verified that it works from the Internet.
  • Eric reminds Mehul that it needs to work from The Client's datacenter—specifically, for the guy doing the migration at The Client.

Day 42

  • Eric confirms that the connection does indeed work from Internet, and that The Client can now proceed with their work.
  • Mehul asks if Eric needs access through The Company network.
  • Eric replies that the connection from The Company network works fine now.

Day 47

  • Ayush requests a meeting with Eric about support handover to operations.

Day 48

  • Eric asks what support is this referring to.
  • James (The Company, person #3) replies that it's about general infrastructure support.

Day 51

  • Eric notifies Ayush and Mehul that server network configurations were incorrect, and that after fixing the configuration and rebooting the server, The Client can no longer log in to the server because the password no longer works.
  • Ayush instructs Vijay to "setup the repository ASAP." Nobody knows what repository he's talking about.
  • Vijay responds that "licenses are not updated for The Company servers." Nobody knows what licenses he is talking about.
  • Vijay sends original root credentials in a plaintext email again.

Day 54

  • Thomas reminds Ayush and Mehul that the servers need to be moved by day 60.
  • Eric reminds Thomas that the deadline was extended to the end of the month (day 75) the previous week.
  • Eric replies to Vijay that the original credentials sent no longer work.
  • Vijay asks Eric to try again.
  • Mehul asks for the details of the unreachable servers, which were mentioned in the previous email.
  • Eric sends a summary of current status (can't access from The Company's network again, server passwords not working) to Thomas, Ayush, Mehul and others.
  • Vijay replies, "Can we discuss on this."
  • Eric replies that he's always reachable by Skype or email.
  • Mehul says that access to private IPs is not under his control. "Looping John and Jared," but no such people were added to the recipient list. Mehul repeats that from The Company's network, private IPs should be used.
  • Thomas tells Eric that the issue has been escalated again on The Service Provider's side.
  • Thomas complains to Roger (The Service Provider, person #5), Theodore (The Service Provider, person #6) and Matthew (The Service Provider, person #7) that the process isn't working.

Day 55

  • Theodore asks Peter (The Service Provider, person #8), Mehul, and Vinod (The Service Provider, person #9) what is going on.
  • Peter responds that websites should be implemented using Netscaler, and asks no one in particular if they could fill an Excel template.
  • Theodore asks who should be filling out the template.
  • Eric asks Thomas if he still thinks the sites can be in production by the latest deadline, Day 75, and if he should install the server on AWS instead.
  • Thomas asks Theodore if configuring the network really takes two weeks, and tells the team to try harder.

Day 56

  • Theodore replies that configuring the network doesn't take two weeks, but getting the required information for that often does. Also that there are resourcing issues related to such configurations.
  • Thomas suggests a meeting to fill the template.
  • Thomas asks if there's any progress.

Day 57

  • Ayush replies that if The Company provides the web service name, The Service Provider can fill out the rest.
  • Eric delivers a list of site domains and required ports.
  • Thomas forwards the list to Peter.
  • Tyler (The Company, person #4) informs Eric that any AWS servers should be installed by Another Service Provider.
  • Eric explains that the idea was that he would install the server on The Company's own AWS account.
  • Paul (The Company, person #5) informs Eric that all AWS server installations are to be done by Another Service Provider, and that they'll have time to do it ... two months down the road.
  • Kane (The Company, person #6) asks for a faster solution, as they've been waiting for nearly two months already.
  • Eric sets up the server on The Company's AWS account before lunch and delivers it to The Client.

Day 58

  • Peter replies that he needs a list of fully qualified domain names instead of just the site names.
  • Eric delivers a list of current blockers to Thomas, Theodore, Ayush and Jagan (The Service Provider, person #10).
  • Ayush instructs Vijay and the security team to check network configuration.
  • Thomas reminds Theodore, Ayush and Jagan to solve the issues, and reminds them that the original deadline for this was a month ago.
  • Theodore informs everyone that the servers' network configuration wasn't compatible with the firewall's network configuration, and that Vijay and Ayush are working on it.

Day 61

  • Peter asks Thomas and Ayush if they can get the configuration completed tomorrow.
  • Thomas asks Theodore, Ayush, and Jagan if the issues are solved.

Day 62

  • Ayush tells Eric that they've made configuration changes, and asks if he can now connect.

Day 63

  • Eric replies to Ayush that he still has trouble connecting to some of the servers from The Company's network.
  • Eric delivers network configuration details to Peter.
  • Ayush tells Vijay and Jai (The Service Provider, person #11) to reset passwords on servers so Eric can log in, and asks for support from Theodore with network configurations.
  • Matthew replies that Theodore is on his way to The Company.
  • Vijay resets the password and sends it to Ayush and Jai.
  • Ayush sends the password to Eric via plaintext email.
  • Theodore asks Eric and Ayush if the problems are resolved.
  • Ayush replies that connection from The Company's network does not work, but that the root password was emailed.

Day 64

  • Tyler sends an email to everyone and cancels the migration.

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

https://thedailywtf.com/articles/best-of-2020-web-server-installation


Метки:  

Best of…: Best of 2020: Science Is Science

Среда, 30 Декабря 2020 г. 09:30 + в цитатник
You do not need formal training from a compsci program or similar before you're allowed to be a developer. But sometimes, when your job role already contains "engineer" in the title, people think you can handle any engineering task. As we continue our review of the best of 2020, here's a tale of misapplied human resources. Original --Remy

Oil well

Bruce worked for a small engineering consultant firm providing custom software solutions for companies in the industrial sector. His project for CompanyX involved data consolidation for a new oil well monitoring system. It was a two-phased approach: Phase 1 was to get the raw instrument data into the cloud, and Phase 2 was to aggregate that data into a useful format.

Phase 1 was completed successfully. When it came time to write the business logic for aggregating the data, CompanyX politely informed Bruce's team that their new in-house software team would take over from here.

Bruce and his team smelled trouble. They did everything they could think of to persuade CompanyX not to go it alone when all the expertise rested on their side. However, CompanyX was confident they could handle the job, parting ways with handshakes and smiles.

Although Phase 2 was officially no longer on his plate, Bruce had a suspicion borne from experience that this wasn't the last he'd hear from CompanyX. Sure enough, a month later he received an urgent support request via email from Rick, an electrical engineer.

We're having issues with our aggregated data not making it into the database. Please help!!

Rick Smith
LEAD SOFTWARE ENGINEER

"Lead Software Engineer!" Bruce couldn't help repeating out loud. Sadly, he'd seen this scenario before with other clients. In a bid to save money, their management would find the most sciency people on their payroll and would put them in charge of IT or, worse, programming.

Stifling a cringe, Bruce dug deeper into the email. Rick had written a Python script to read the raw instrument data, aggregate it in memory, and re-insert it into a table he'd added to the database. Said script was loaded with un-parameterized queries, filters on non-indexed fields, and SELECT * FROM queries. The aggregation logic was nothing to write home about, either. It was messy, slow, and a slight breeze could take it out. Bruce fired up the SQL profiler and found a bigger issue: a certain query was failing every time, throwing the error Cannot insert the value NULL into column 'requests', table 'hEvents'; column does not allow nulls. INSERT fails.

Well, that seemed straightforward enough. Bruce replied to Rick's email, asking if he knew about the error.

Rick's reply came quickly, and included someone new on the email chain. Yes, but we couldn't figure it out, so we were hoping you could help us. Aaron is our SQL expert and even he's stumped.

Product support was part of Bruce's job responsibilities. He helpfully pointed out the specific query that was failing and described how to use the SQL profiler to pinpoint future issues.

Unfortunately, CompanyX's crack new in-house software team took this opportunity to unload every single problem they were having on Bruce, most of them just as basic or even more basic than the first. The back-and-forth email chain grew to epic proportions, and had less to do with product support than with programming education. When Bruce's patience finally gave out, he sent Rick and Aaron a link to the W3 schools SQL tutorial page. Then he talked to his manager. Agreeing that things had gotten out of hand, Bruce's manager arranged for a BA to contact CompanyX to offer more formal assistance. A teleconference was scheduled for the next week, which Bruce and his manager would also be attending.

When the day of the meeting came, Bruce and his associates dialed in—but no one from CompanyX did. After some digging, they learned that the majority of CompanyX's software team had been fired or reassigned. Apparently, the CompanyX project manager had been BCC'd on Bruce's entire email chain with Rick and Aaron. Said PM had decided a new new software team was in order. The last Bruce heard, the team was still "getting organized." The fate of Phase 2 remains unknown.

[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.

https://thedailywtf.com/articles/best-of-2020-science-is-science


Метки:  

Best of…: Best of 2020: The Time-Delay Footgun

Вторник, 29 Декабря 2020 г. 09:30 + в цитатник
As we revisit the best articles of 2020, have you been wondering why 2020 has been such a… colorful year? Maybe the developer responsible wrote a bad version check. Original --Remy

A few years back, Mike worked at Initech. Initech has two major products: the Initech Creator and the Initech Analyzer. The Creator, as the name implied, let you create things. The Analyzer could take what you made with the Creator and test them.

For business reasons, these were two separate products, and it was common for one customer to have many more Creator licenses than Analyzer licenses, or upgrade them each on a different cadence. But the Analyzer depended on the Creator, so someone might have two wildly different versions of both tools installed.

Initech wasn’t just incrementing the version number and charging for a new seat every year. Both products were under active development, with a steady stream of new features. The Analyzer needed to be smart enough to check what version of Creator was installed, and enable/disable the appropriate set of features. Which meant the Analyzer needed to check the version string.

From a user’s perspective, the version numbers were simple: a new version was released every year, numbered for the year. So the 2009 release was version 9, the 2012 was version 12, and so on. Internally, however, they needed to track finer-grained versions, patch levels, and whether the build was intended as an alpha, beta, or release version. This meant that they looked more like “12.3g31”.

Mike was tasked with prepping Initech Analyzer 2013 for release. Since the company used an unusual version numbering schema, they had also written a suite of custom version parsing functions, in the form: isCreatorVersion9_0OrLater, isCreatorVersion11_0OrLater, etc. He needed to add isCreaterVersion12_0OrLater.

“Hey,” Mike suggested to his boss, “I notice that all of these functions are unique, we could make a general version that uses a regex.”

“No, don’t do that,” his boss said. “You know what they say, ‘I had a problem, so I used regexes, now I have two problems.’ Just copy-paste the version 11 version, and use that. It uses string slicing, which performs way better than regex anyway.”

“Well, I think there are going to be some problems-”

“It’s what we’ve done every year,” his boss said. “Just do it. It’s the version check, don’t put any thought into it.”

“Like, I mean, really problems- the way it-”

His boss cut him off and spoke very slowly. “It is just the version check. It doesn’t need to be complicated. And we know it can’t be wrong, because all the tests are green.”

Mike did not just copy the version 11 check. He also didn’t use regexes, but patterned his logic off the version 11 check, with some minor corrections. But he did leave the version 11 check alone, because he wasn’t given permission to change that block of code, and all of the tests were green.

So how did isCreatorVersion11_0OrLater work? Well, given a version string like 9.0g57 or 10.0a12, or 11.0b9, it would start by checking the second character. If it was a ., clearly we had a single digit version number which must be less than 11. If the second character was a 0, then it must be 10, which clearly is also less than 11, and there couldn't possibly be any numbers larger than 11 which have a "0" as their second character. Any other number must be greater than or equal 11.

Mike describes this as a “time-delayed footgun”. Because it was “right” for about a decade. Unfortunately, Initech Analyzer 2020 might be having some troubles right now…

Mike adds:

Now, I no longer work at Initech, so unfortunately I can’t tell you the fallout of what happened when that foot-gun finally went off this year.

[Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!

https://thedailywtf.com/articles/best-of-2020-the-time-delay-footgun


Метки:  

Best of…: Best of 2020: Copy/Paste Culture

Понедельник, 28 Декабря 2020 г. 09:30 + в цитатник
As per usual, we'll be spending a few days looking back at some of our favorite stories of the year. We start with a visit to a place where copy/pasting isn't just common, it's part of the culture. Original -- Remy

Mark F had just gone to production on the first project at his new job: create a billables reconciliation report that an end-user had requested a few years ago. It was clearly not a high priority, which was exactly why it was the perfect items to assign a new programmer.

"Unfortunately," the end user reported, "it just doesn't seem to be working. It's running fine on test, but when I run it on the live site I'm getting a SELECT permission denied on the object fn_CalculateBusinessDays message. Any idea what that means?"

The problem was fairly obvious, and Mark knew exactly what the error meant. But the solution wasn't so obvious. Why did the GRANT script work fine in test, but not in production? How can he check to see what the GRANTS are in production? Is there someone specific he should ask to get permission to look himself? Does the DBA team use a sort of ticketing system maybe? Is this even the right approach? Who on his team could he even ask?

Fortunately, Mark had the perfect venue to ask these sorts of questions: the weekly one-on-one with his team lead, Jennifer. Although he had a few years of coding experience under his belt, he was brand new to The Enterprise and specifically, how large organizations worked. Jennifer definitely wasn't the most technical person he'd met, but she was super helpful in "getting unblocked" as he was learning to say.

"Huh", Jennifer answered in their meeting, "first off, why do you even need a function to calculate the business days between two dates?"

"This seems like something pretty common in our reports," Mark responded, "and this, if the logic ever changes, we only need to change it in one place."

Jennifer gave a mystified look and smiled, "Changes? I don't think the 7-day week is going to change anytime soon, nor is the fact that Saturday and Sunday are weekends."

"Well, umm," Mark definitely didn't expect that response. He was surprised to have to explain the basic principles of code reuse to his supposed mentor, "you see, this way we don't have to constantly rewrite the logic in all the places, so the code is a bit simpler."

"Why don't you just copy/paste the calculation code in your queries?" she rhetorically asked. "That seems like it'd be a lot simpler to me. And that's what I always do…. But if you really want to get the DBAs involved, your best contact is that dba-share email address. They are super-slow to project tickets, but everyone sees that box and they will quickly triage from there."

Needless to say, he didn't follow Jennifer's programming advice. She was spot on about how to work with the DBA team. That tip alone saved Mark weeks of frustration and escalation, and helped him network with a lot more people inside The Enterprise over the years.

##

Mark's inside connections helped, and he eventually found himself leading a team of his own. That meant a lot more responsibilities, but he found it was pretty gratifying to help others "get unblocked" in The Enterprise.

One day, while enjoying a short vacation on a beach far, far away from the office, Mark got a frantic call from one of his team members. An end-user was panicked about a billables reconciliation report that had been inaccurate for months. The auditors had discovered the discrepancies and needed answers right away.

"So far as I can tell," his mentee said, "this report is using a fn_ CalculateBusinessDays function, which does all sorts of calculations for holidays, but they already prorate those on the report."

The problem was fairly obvious, and Mark knew exactly what happened. Some must have changed the logic on that function to work for their needs. But changing it back would mean breaking someone else's report. And the whole idea of a function seemed strange, because that would mean taking a dependen--

The junior programmer interrupted his stream of thought.

"I think I should just add an argument to the function to not include holidays," he said. "That's really simple to do, and we can just edit our report to use that argument."

"Ehhh," Mark hesitated, "the logic is so simple. Why don't you just copy/paste the business day calculation? That's the simplest solution… that's what I do all the time."

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

https://thedailywtf.com/articles/best-of-2020-copy-paste-culture


Метки:  

CodeSOD: Classic WTF: 2012

Пятница, 25 Декабря 2020 г. 09:30 + в цитатник
As we enjoy our holiday today, in this seemingly unending year of 2020, our present to you is a blast from 2012, the year the world was supposed to end. Original --Remy

"Most people spend their New Year's Eve watching the ball drop and celebrating the New Year," writes Jason, "and actually, that's what I planned to do, too. Instead, I found myself debugging our licensing activation system." "Just as I was about to leave the office, I received a torrent of emails with the subject 'License Activation Failed'. One or two every now and then is expected, but dozens and dozens at four o'clock on New Year's Eve... not so good. It took me a moment to realize the significance of 4:00PM, but then it hit me: I'm on Pacific Time, which is UTC -8 hours.

"The error message that was filling up our logs was simply 'INVALID DATE' and for the life of me I couldn't figure out why. Our license code was a 32-bit number that represented the expiration date of the license and the features in the license. 7 of those bits represented the year since 2000, so obviously the date was fine up until 2127. After hours and hours of digging through PL/SQL, Java, JavaScript, Ruby, and some random shell scripts, I found the following.

IF YEAR = 2012 GOTO INVALIDDATE

Jason continued, "nowhere in the code was any indication why 12 would not work, so I took it out. Figuring it couldn't make things any worse, I published the code and tested the registration system. It worked. In the end, a meaningless IF statement had shut down our renewals business... just because."

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

https://thedailywtf.com/articles/classic-wtf-2012


Метки:  

CodeSOD: Classic WTF: Developer Carols

Четверг, 24 Декабря 2020 г. 09:30 + в цитатник
It's the holiday season, which means over the next few days, we'll be reviewing some of the best of 2020, if anything about 2020 can be considered "the best", and maybe some other surprises. To kick things off, we're going to pull from the faroff year of Christmas 2017, and return to our Developer Carols. That year, we ran them too late to go caroling, and this year, nobody outside of New Zealand should be going caroling, keeping with our tradition of meeting the requirements but delivering absolutely no value. (Original)
'Arbol navide~no luminoso en Madrid 02

It’s Christmas, and thus technically too late to actually go caroling. Like any good project, we’ve delivered close enough to the deadline to claim success, but late enough to actually be useless for this year!

Still, enjoy some holiday carols specifically written for our IT employees. Feel free to annoy your friends and family for the rest of the day.

Push to Prod (to the tune of Joy To the World)

Joy to the world,
We’ve pushed to prod,
Let all,
record complaints,
“This isn’t what we asked you for,”
“Who signed off on these requirements,”
“Rework it,” PMs sing,
“Rework it,” PMs sing,
“Work over break,” the PMs sing.


Backups (to the tune of Deck the Halls)

Back the system up to tape drives,
Fa la la la la la la la la,
TAR will make the tape archives,
Fa la la la la la la la la,
Recov'ry don't need no testing,
Fa la la la la la la la la la,
Pray it works upon requesting,
Fa la la la la la la la la


Ode to CSS (to the tune of Silent Night)

Vertical height,
Align to the right,
CSS,
Aid my fight,
Round the corners,
Flattened design,
!important,
Please work this time,
It won't work in IE,
Never in goddamn IE


The Twelve Days of The Holiday Shift (to the tune of The Twelve Days of Christmas)

On my nth day of helpdesk, the ticket sent to me:
12 write arms leaping
11 Trojans dancing
10 bosses griping
9 fans not humming
8 RAIDs not striping
7 WANs a-failing
6 cables fraying
5 broken things
4 calling users
3 missing pens
2 turtled drives
and a toner cartridge that is empty.

(Contributed by Charles Robinson)


Here Comes a Crash Bug (to the tune of Here Comes Santa Claus)

Here comes a crash bug,
Here comes a crash bug,
Find th’ culprit with git blame,
Oh it was my fault,
It’s always my fault,
Patch and push again.

Issues raisin‘, users ‘plainin’,
Builds are failin’ tonight,
So hang your head and say your prayers,
For a crash bug comes tonight.


WCry the Malware (to the tune of Frosty the Snowman)

WCry the Malware, was a nasty ugly worm,
With a cryptolock and a bitcoin bribe,
Spread over SMB

WCry the Malware, is a Korean hack they say,
But the NSA covered up the vuln,
To use on us one day

There must have been some magic in that old kill-switch they found,
For when they register’d a domain,
The hack gained no more ground

WCry the Malware, was as alive as he could be,
Till Microsoft released a patch,
To fix up SMB

(Suggested by Mark Bowytz)


Oh Come All Ye Web Devs (to the tune of Oh Come All Ye Faithful)

Oh come, all ye web devs,
Joyful and triumphant,
Oh come ye to witness,
JavaScript's heir:

Come behold TypeScript,
It’s just JavaScript,
But we can conceal that,
But we can conceal that,
But we can conceal that,
With our toolchain


Thanks to Jane Bailey for help with scansion. Where it's right, thank her, where it's wrong, blame me.

[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.

https://thedailywtf.com/articles/classic-wtf-developer-carols


Метки:  

Поиск сообщений в rss_thedaily_wtf
Страницы: 124 ... 100 99 [98] 97 96 ..
.. 1 Календарь