FroshKiller All American 51911 Posts user info edit post |
Well, it's not "the latest," and I have to think you've read it already, but Code Complete by Steve McConnell is required reading. Chapter 3 focuses on the prereqs of project planning. Chapter 28 is devoted to the management of a software development project. Chapter 33 has some further reading suggestions.
The Pragmatic Programmer by Dave Thomas and Andrew Hunt focuses on project planning and management in chapters 7 & 8. You could argue that it's basic knowledge, but it's basic knowledge motherfuckers don't put into practice, and I think the book has a lot of great tips for making sure you and others do the right thing instead of the easy thing.
[Edited on December 6, 2018 at 10:50 AM. Reason : Peace, we outta here.] 12/6/2018 10:50:31 AM |
Lionheart I'm Eggscellent 12775 Posts user info edit post |
Quote : | "You could argue that it's basic knowledge, but it's basic knowledge motherfuckers don't put into practice, " |
Yeah this is kind of where I'm hoping to kind of look for some pragmatic suggestions for incremental improvements. I mean I've practically thrown a copy of mythical man month at a managers face before for doing stupid shit that we've known is stupid for 40 years, but like most things there's all this advice and research that no one ever actually follows.
Basically my job is going to be as much cultural shift as anything else, getting our various PMs and HODs to stop falling into the trap of just turning on a dime and throwing resources late at whatever the current squeeky wheel is and thereby not only spending more time to transition than it would have been to stay the course but also making everybody miserable and what not.
Biggest challenges is that we are so lean and we can't go to a true Agile due to the QM and industry requirements we have to meet.12/6/2018 11:33:25 AM |
FroshKiller All American 51911 Posts user info edit post |
Lightly anonymized, but the code is actually this verbose:
Public Function IsTraditionalAndCompanyBM(ByVal ClientId As Int64) As Boolean Return SwissArmyKnife.GetBooleanValue(New FrameworkDataAccessLayer.Lookup.ClientTableLookup(FrameworkDataAccessLayer.Data.SourceType.Primary).GetClient(ClientId)?.AllowCompanyInvitations)
End Function
I don't know exactly what this is supposed to do, but it's in a fucking utility class that's about 15,000 lines at this point. All this does is run a goddamn database query and return a field value from the model type that corresponds to the database table.6/11/2019 3:29:25 PM |
aaronburro Sup, B 53062 Posts user info edit post |
Been pulled in to drag a UI system across the finish line in a server migration. First thing I notice is that every single window is opened and created on it's own thread; and none of those threads are cleaned up when the window is closed. Oh, and the VM's are created on a different thread, before the corresponding window is created, and in 5he VM's constructor, they try to capture the Dispatcher... which is guaranteed to be the wrong one
Next thing I notice is Thread.Sleep(2000) at the beginning of every single request for data to the server. Fucking awesome. And they still are getting incorrect data in asynchronously-loaded drop downs, because checking that you don't respond to out of order responses is an impossible task.
[Edited on July 9, 2019 at 11:23 PM. Reason : ] 7/9/2019 11:09:56 PM |
wwwebsurfer All American 10217 Posts user info edit post |
Quote : | "Next thing I notice is Thread.Sleep(2000) at the beginning of every single request for data to the server." |
Good news is that any performance targets you have will now be easily achievable once you, ya know, fix the code 7/10/2019 12:03:21 AM |
smoothcrim Universal Magnetic! 18966 Posts user info edit post |
working on a service where we've (foolishly) decided to build a global edge network. I'm brought on to help this poorly run project. immediately I suggest simplifying the stack just because the doc alone is too complicated to make it through, let alone supporting it day to day. I write a simple poc with a central work dispatcher in AWS with consumers to pull stuff off the relevant queues at the edges. they ask for a big presentation on it and then the next day present their plans going forward where they plan to put an entire redundant control plane (~8U) in every deployment
I can't share code samples, but it's effectively passing static config back and forth on redis
quit the same day for a better job 7/12/2019 1:13:04 AM |
FroshKiller All American 51911 Posts user info edit post |
wondering how you define "better job" because holy shit talk about collecting a check for taking a nap
you could've worked there for years and only done a few weeks of work
[Edited on July 12, 2019 at 10:08 AM. Reason : ///] 7/12/2019 10:08:21 AM |
smoothcrim Universal Magnetic! 18966 Posts user info edit post |
i've quit every job i've ever had because i was bored, so it was par for the course. i literally built the same service at amazon 6 years ago and it's still running today, but hey, what do i know?
anyway, new job is super cool. squarely in the research org building net new tech and turning it into products. i probably work less, not having to explain the same shit to people that don't get it every day. 7/13/2019 8:38:02 AM |
Lionheart I'm Eggscellent 12775 Posts user info edit post |
Not specifically design or engineering related but a major annoyance:
Nothing will make me respect you less professionally than having to watch you spend a ton of time doing something simple from the command line just to show off how "smart" you are.
Was on a call supporting a client with some troubleshooting and asked them to copy over a diagnostic tool to their server. They proceeded to open the command prompt navigate directory by directory stopping at each level to do a full directory listing, finally making it to the target calling a mkdir with the wrong name, deleting, making it again, just to proceed to open up an explorer window and drag and drop the package in there. 7/18/2019 2:00:10 PM |
FroshKiller All American 51911 Posts user info edit post |
I came across a dumb pattern in an internal application where we had a dirt-stupid interface for rendering some buttons on a web page for various functions related to the screen you were viewing.
The interface just requires you to implement a function that returns a string instead of something sane like a list of control instances. The dumb pattern is that people had taken to generating handwritten HTML for an unordered list where each list item held a handwritten anchor element.
I thought, "There must be a better way," and proceeded to write a base class for these screens that had a collection property of actual instances of an actual link control from our first-party framework controls. The base class implements the button interface, and that function just renders our collection of link controls consistently.
Except I noticed that the screen didn't look quite right cosmetically, because the link style wasn't consistent with what had been handwritten. Should've been like this:
<ul class="menu-buttons"> <li> <a class="menu-button" href="whatever">Button Caption</a> </li> </ul>
Instead, each anchor was wrapped in a div:
<ul class="menu-buttons"> <li> <div> <a class="menu-button" href="whatever">Button Caption</a> </div> </li> </ul>
I recalled the default rendering method for our link control wraps everything in a div and thought I remembered that there was a property to control that behavior. Sure enough, I saw a Boolean field called WrapControlInDiv. I set that to false and...nothing changed.
So I pulled the code for the link control and searched for a reference to WrapControlInDiv. Nothing.
Then I noticed that WrapControlInDiv was a member of the base class, but someone had implemented a property called DoNotWrapWithDiv on the link class that was completely unrelated to the fucking base class field...yet the rendering method honored that one....
[Edited on August 5, 2019 at 2:18 PM. Reason : ///]8/5/2019 1:58:34 PM |
aaronburro Sup, B 53062 Posts user info edit post |
Found a utility class in our codebase the other day that is intended to be used for thread synchronization... and the class isn't thread-safe.
It wasn't being used, so I deleted it immediately 11/8/2019 7:40:32 AM |
smoothcrim Universal Magnetic! 18966 Posts user info edit post |
Quote : | "we're going to write a web service in c++ so it'll be fast" |
Quote : | "forget REST, we'll use lib-websockets" |
Quote : | "we'll keep state in leveldb because it's super fast" |
but how will we not be bottlenecked by a database that can only support a single thread and a single process accessing it?
Quote : | "then you build it" |
ok11/8/2019 12:47:54 PM |
aaronburro Sup, B 53062 Posts user info edit post |
Helped fix a deadlock in another app's messaging layer yesterday. Diagnosed it fairly quickly, and fixed it by making changes in the messaging client wrapper (single-threaded message queues by vendor... ). The guy I was helping then says "I guess I can use this same solution in the other wrappers for this message bus, too, right?"
That explained a good bit of the shit I briefly saw. Like the Semaphore(1) on their asynchronous message method 11/15/2019 7:38:14 AM |
FroshKiller All American 51911 Posts user info edit post |
PersonDetails = GetLocationFromPerson(Nothing, Nothing, Nothing, Nothing, AccountNumber)
"What the hell is a 'code smell'?"11/15/2019 11:28:41 AM |
aaronburro Sup, B 53062 Posts user info edit post |
VB, itself, is a code smell 11/16/2019 11:14:55 PM |
FroshKiller All American 51911 Posts user info edit post |
I've been posting VB in this thread for, like, five years. Nobody's choosing to work in VB. It's two big legacy projects. Like three people high up the food chain made architectural decisions over a decade ago that the rest of us have been living with.
That said, that code's just as bad in any other language. That it happens to be in VB is irrelevant. Why do we even have a function with five parameters (which is borderline to me)? Why is the seemingly most important parameter the last one? Why isn't there an overloaded definition? Why are we not at least passing the arguments by name for clarity (and no, there is no parameter array).
You might say it's unfair to ding the person who checked this in for the definition of the method, but the plain fact is that if you know enough about the internals of the function to know that you'll get your desired result by passing null for four out of five arguments, you are probably in a position to do something about it. 11/20/2019 6:36:12 AM |
aaronburro Sup, B 53062 Posts user info edit post |
Straight pulled an offshore employee off of a project a couple weeks ago. I'm reviewing her code for some rearchitecting changes to a core part of our system and I see wholesale blocks of guard code being removed, all over the application. This code is basically protecting the app from multiple scenarios that just aren't supported yet, and she just completely removed them. I asked her why and she said, no kidding, "they were preventing my code changes from working. Like, they kept hitting that code and logging errors and warnings." In case you are curious, no, her code changes weren't to actually address the reasons the guards were put there in the first place.
Needless to say, her pull requests were rejected. Interestingly enough, she was tasked a few days later with some unrelated changes, and when I looked at them, she had taken every single piece of code from the other branch that got rejected and put them into her new branch. All of this was *after* she had tried to get these PRs into our release branch without the corresponding server changes being finished or even scheduled for the release (which would have completely broken the application by changing core message schemas).
After both I and her manager (who doesn't report to anyone in my management chain until at least the CIO, great setup, right?) reamed the fuck out of her for such ridiculous behaviour, I haven't seen a single commit from her in over two weeks.] 5/5/2020 12:14:01 AM |