CapnObvious All American 5057 Posts user info edit post |
Fake it until you make it. This is apparently a big thing in Asian countries where they have someone fake a resume for you. You get your first job and get fired a few weeks later. You get your second job and last a little longer until they also fire you. Rinse and repeat until you have enough skills where firing you is more effort than just cleaning up after you. 10/19/2016 4:20:12 PM |
aaronburro Sup, B 53136 Posts user info edit post |
Two weeks later, and they can finally get the second environment up without crashing the first one. PROGRESS!!!
In other news, some offshore guys decided they had to upgrade from Java 6 to Java 8 this weekend. Compiled it in Java 8, builds successfully, so they deploy it straight to production. Did they ever actually run it in UAT? Of course not. Needless to say, that deploy got rolled back about 9:05AM Monday morning.] 10/25/2016 7:11:49 PM |
Lionheart I'm Eggscellent 12776 Posts user info edit post |
Lol what sort of environment allows an upgrade like that without a UAT/OQ/PQ testing phase. Maybe I'm just oo used to being in the GMP space that this sounds insane to me. 10/26/2016 2:53:57 PM |
Fry The Stubby 7784 Posts user info edit post |
^^ o_O 10/26/2016 9:31:56 PM |
aaronburro Sup, B 53136 Posts user info edit post |
^^ Oh, they "deployed it to UAT," but never actually tested it. 10/26/2016 11:47:25 PM |
CaelNCSU All American 7132 Posts user info edit post |
Quote : | "but I did my usual check of the SVN logs to see where I might run into merge issues." |
What is this? 2006?11/19/2016 11:08:14 PM |
aaronburro Sup, B 53136 Posts user info edit post |
You've seen the shit I've posted in this thread. These morons can barely handle SVN. Just getting them to always merge the damn root folder is hard enough. Hell, I'm just happy when they actually use merge in the first place. I shudder to think how badly they would fuck up a Git repo. 11/22/2016 1:01:38 AM |
FroshKiller All American 51913 Posts user info edit post |
We have a report scheduling feature that delivers multiple reports to email. The report engine and email engine are loosely coupled and communicate through the database. There is a queue of report requests and a queue of email requests.
The report scheduler creates records in each queue. Each schedule has a unique ID, and that unique ID is set on both the report requests and the email requests. Using this value, the email engine can query for report requests with the same schedule ID to determine whether the report output is ready without having to communicate directly with the report engine.
Some bright boy working on a totally separate feature decided to exploit this particular implementation detail so the application could generate a certain document on demand and email it without requiring the normal report schedule setup. He (or she, maybe, I don't really know) did this by fabricating a schedule ID.
The schedule ID is an integer that normally increases in sequence. However, since there's no foreign key constraint between the report queue and the schedule, you can use whatever integer you want on the report requests. This would be a big enough problem had it not been for the completely stupid way our bright boy or girl decided to generate the made-up schedule ID.
It's literally just concatenating the hour, minute, and second of the application host's time and converting that to an integer.
The particular method results in some fun situations, like documents generated for a request entered at 11:19:32 a.m. being included in the outgoing email for a separate request entered at 1:19:32 p.m. (fake schedule ID 11932 in both cases).
And even more amusingly, this can occur across days. Weeks. Months. Years.
Even more amusingly, it's not limited to this rogue feature. If the fake schedule IDs collide with real schedule IDs, sensitive financial reports could go out to God knows whom.
And even more amusingly, that scenario is likely. We generally don't clear records from the queues once they're completed, because they're useful for auditing and troubleshooting. Neither do we generally remove report output generated by the report scheduler, since it all lives in the file system in handy archive folders and might be useful for auditing as well. 11/22/2016 8:30:22 AM |
aaronburro Sup, B 53136 Posts user info edit post |
Quote : | " The report engine and email engine are loosely coupled and communicate through the database." |
I didn't need to read any further11/23/2016 1:35:43 AM |
FroshKiller All American 51913 Posts user info edit post |
That was admittedly a bit tongue-in-cheek. 11/23/2016 8:19:29 AM |
CaelNCSU All American 7132 Posts user info edit post |
With most git hosting you can deny write access to the mainline branch and force merge/pull requests through a review process. Since everything is generally branch focused you can isolate the damage they can do to the feature or bug they are working on. 11/29/2016 4:22:29 PM |
aaronburro Sup, B 53136 Posts user info edit post |
In a sane development process, I would agree. But our offshore guys cry up the chain to managers four and five levels up when they fail a code review for putting a click-event handler in code-behind. They complain that we don't treat them as competent devs. So then their garbage ends up going into the repo anyway. Keeping them or other people from committing is a battle that we'll lose anyway, cause upper management still sees offshore as a cost-cutting measure with no impact on development quality, despite all evidence to the contrary. 12/3/2016 2:02:49 PM |
raiden All American 10505 Posts user info edit post |
got a vendor that we do business with, have spent $millions on, and they're shitty.
they don't version control their code. We have some of the source, and they'll just have shit from previous versions commented out in the code. Like whole blocks of code just commented out because they don't version control.
They don't really do much QA either, and their code review process is horrible to say the least.
I'm working on trying to convince the higher ups to drop this vendor like a bad habit. 12/18/2016 4:48:04 PM |
CaelNCSU All American 7132 Posts user info edit post |
^
[Edited on December 18, 2016 at 10:48 PM. Reason : a] 12/18/2016 10:48:16 PM |
moron All American 34183 Posts user info edit post |
^^ is that in their code product or a one-off tool? I could see that in some script or temporary solution. 12/21/2016 12:31:51 AM |
FroshKiller All American 51913 Posts user info edit post |
Anonymized, but I shit you not:
Public Function GetCurrentDate() As Date If DatabasePlatform = "MSSQL" Return GetDateValueFromDatabase("select getdate()") Else Return GetDataValueFromDatabase("select sysdate from dual") End If End Function
[Edited on December 21, 2016 at 11:14 AM. Reason : ///]12/21/2016 11:14:08 AM |
afripino All American 11433 Posts user info edit post |
what if the system date on the db server is different from the current date on the client system? I dunno...I don't see the huge problem with ^, then again, I ain't no nerd. plz to elaborate?
or is it passing the query as a parameter?
[Edited on December 21, 2016 at 3:13 PM. Reason : ] 12/21/2016 3:12:06 PM |
FroshKiller All American 51913 Posts user info edit post |
Passing the query as a parameter isn't really the problem. I anonymized it, but this is more representative of the real code:
Return UtilityClass.GetDateFromObject(DatabaseClient.GetValueFromQuery("select getdate()"))
I can assure you that this is being used to get the current date in the application server's context, and that is enough for it to be stupid. The function name is just GetCurrentDate, that part is not anonymized. Believe me that even in the imaginary world where this is being used to check the time in the database server's context, it's still stupid, because there isn't really a plausible use case for that. Why bother establishing a database connection and running a query when any server you like provides some kind of time RPC?12/21/2016 5:05:32 PM |
aaronburro Sup, B 53136 Posts user info edit post |
My favourite part is that it assumes you've either got SQL Server or Oracle. Fuck anything else 12/23/2016 1:01:40 AM |
FroshKiller All American 51913 Posts user info edit post |
I will defend that one the one hand because SQL Server and Oracle are the only platforms the application supported, and that was clearly listed in the system requirements....
...then I will condemn that on the other hand because we dropped support for Oracle entirely as of our last major version, have no clients using Oracle, yet we've left all the Oracle crap in the code. 12/23/2016 6:03:38 AM |
raiden All American 10505 Posts user info edit post |
Quote : | "^^ is that in their code product or a one-off tool? I could see that in some script or temporary solution.
" |
its code product.
I'm currently fighting an uphill (but starting to gain some ground) battle to dump this vendor.12/23/2016 11:50:51 AM |
raiden All American 10505 Posts user info edit post |
I got another story to tell. One of my predecessors, who is no longer working here, had a design where he had 2 servers that were supposed to be load balancers. They were configured as an HA pair with a VIP, and were supposed to be configured to load balance traffic between two more servers downstream (which feeds multiple downstream nodes).
The fuckhead couldn't get that last part to work, so he has the two "load balancers" just redirecting all traffic to a single server (which feeds multiple downstream nodes).
Yep, we go from redundancy to single point of failure back to redundancy - because he couldn't figure out how to get shit to work and even better, he didn't tell anyone, didn't update any documentation or designs, fucking nothing. So, of course when shit failed, we're looking thru the all the documentation and that doesn't match up with what's actually configured.
long story short, spent a while cleaning that shit up.
I got more stories about this guy. Like how he has random perl scripts that read logs, send that output to another file, call another perl script to send an email about it, and then call another perl script to back it all up. Each of these perl scripts are only about 20-30 lines - at most - so yeah, dumbass. 1/7/2017 3:19:36 PM |
Lionheart I'm Eggscellent 12776 Posts user info edit post |
Quote : | "I will defend that one the one hand because SQL Server and Oracle are the only platforms the application supported, and that was clearly listed in the system requirements....
...then I will condemn that on the other hand because we dropped support for Oracle entirely as of our last major version, have no clients using Oracle, yet we've left all the Oracle crap in the code." |
Yeah functions like that I actually don't have an issue with because it just screams "TIMELINES!!!". You write functions like that because you don't have the time and energy to make something nice and future proof while you have to write the actual features everywhere else because sales or planning doesn't know shit about actually making anything.1/8/2017 9:31:45 AM |
aaronburro Sup, B 53136 Posts user info edit post |
Discovered today that we open windows incorrectly in our application. A wonderful side effect is rooting every single window (and its data) in the application, forever. On the bright side, the contractors we paid to write it only cost 3 times what a regular employee would cost
[Edited on January 18, 2017 at 9:46 PM. Reason : ] 1/18/2017 9:45:37 PM |
aaronburro Sup, B 53136 Posts user info edit post |
A simplified version of the code, but... Here is how you turn O(log(N)) into O(N). For when O(log(N)) is just too damned fast and you need to tame that shit
public string GetAlias(Foo foo) { var dict = new Dictionary(); foreach (var thingy in _coherenceCache.EnumerateEverythingInTheCache()) { dict[thingy.Key] = thingy.Value; }
Value val; dict.TryGetValue(foo.Id, out val);
return out ?? foo.SomeOtherProperty; }
1/24/2017 10:07:45 PM |
FroshKiller All American 51913 Posts user info edit post |
What kind of collection is _coherenceCache? Or I guess more importantly, what kind of collection does the EnumerateEverythingInTheCache function return? Some kind of collection of KeyValuePairs?
I know it's futile to reason about this in a vacuum, but the property accesses on the Foo type in this function bug me. Is this supposed to be an extension method for the Foo type?
Why do I get the feeling that EnumerateEverythingInTheCache is packed with side effects? 1/25/2017 7:15:27 AM |
aaronburro Sup, B 53136 Posts user info edit post |
_coherenceCache is a wrapper around a Coherence Cache. The EnumerateEverythingInTheCache() function just returns an enumeration of items that were read from the cache (potentially over the network, too). They are kind of KeyValuePair, but they are pretty much backwards. The "value" portion is what we actually want to search by, because it's what's on Foo. This isn't an extension method, though its location in the codebase is also a bit on the stupid side, but that's for another discussion.
Consider that GetAlias() is called for each Foo as it's read off a separate query service, while the items in _coherenceCache rarely (if ever) change. The Dictionary is a great idea, except for the fact that it gets built for every call to this function, iterating every item in the cache, which requires O(N) operations at a minimum. This was written to avoid calling FirstOrDefault(), but the implementation is far less efficient than FirstOrDefault(). 1/25/2017 10:28:57 PM |
FroshKiller All American 51913 Posts user info edit post |
An instance method in a class of over 3,500 lines:
Public Function MaskSensitiveValue(ByVal ValueToMask As String) As String Dim MaskedValue As String = ""
If ValueToMask <> "" Then MaskedValue = "********" End If
Return MaskedValue End Function
[Edited on February 10, 2017 at 8:18 PM. Reason : force of habit]2/10/2017 8:18:49 PM |
aaronburro Sup, B 53136 Posts user info edit post |
Well, your first hint of stupidity is that it's VB. I wouldn't look any further than that. 2/12/2017 12:03:52 AM |
synapse play so hard 60940 Posts user info edit post |
Legacy code mane. It's everywhere. 2/13/2017 12:12:13 AM |
FroshKiller All American 51913 Posts user info edit post |
Let's appreciate its stupidity in Python, then:
def mask_sensitive_value(value_to_mask): masked_value = ""
if value_to_mask == "": masked_value = "********"
return masked_value
This function will only ever return an empty string or a string of eight asterisks. Nothing about the parameter matters except whether its length is nonzero. So why the fuck provide the sensitive value at all?
But it's really stupid in VB. It's an instance method, so every instance of the utility class allocates memory for that local variable MaskedValue. You know, the string that will only ever be an empty string or eight asterisks? There's no reason those shouldn't be constants, and if they can be constants, the method can be declared Shared.
Private Const SensitiveValueMask As String = "********" Private Const EmptySensitiveValueMask As String = ""
Public Shared Function MaskSensitiveValue(ByVal ValueToMask As String) As String If ValueToMask <> "" Then Return SensitiveValueMask Else Return EmptySensitiveValueMask End If End Function 2/13/2017 6:12:52 AM |
CaelNCSU All American 7132 Posts user info edit post |
The setup: using a JSON based database in a Java web app. It's fast because #webscale because the database is in memory.
Architectural Assumptions Made:
1) Since the database is in memory you don't have to have to worry about data size, 2 - 20 MB documents are fine, memory is cheap and coming down in price all the time. 2) Since RxJava allows for async operations you can make 1000 requests to the database per single request to the app. 3) To scale on the api side you divide all the work, no matter how minor, into service calls. So a request comes in--don't actually make the request to the DB, send the message to another box to get the data, and send it back to the requesting node. Why use a load balancer to scale? 4) Since you are using JSONObjects you can just send them around and not worry about a type. Then on every method call you can implement the type checking your self with logic like: if object.contains(x) && object.contains(y). 5) Since the database is sharded by a hash of an ID at random you can scale horizontally! 6) Since the database is in memory it's fast and you don't need a cache.
SHOCKING findings: So if you profile the app, the actual database vendor driver pegs the CPU to almost 100%--because of the document size. You can see the DB parse code is on CPU 70 - 80% of the time doing work. After the driver parses the document the app server immediately serializes the message and immediately reparses it into another type of JSON object because of the serialization steps. The database gets effectively DDOS'd since so many app servers are needed for even minor load. The access pattern we had is 99% of requests go to a small set of documents, so sharding randomly by hash key doesn't distribute the load at all for reads. Code is super error prone since lots of runtime types are checked instead of using compile time type checking--we should have just used node. Being in memory doesn't prevent the wait time for network calls, especially since machines have a fixed number of threads with which to send requests.
You do actually need a cache, always, and especially in this case. 2/13/2017 11:45:04 AM |
FroshKiller All American 51913 Posts user info edit post |
oh my god that is call for an ass-beating 2/13/2017 1:18:03 PM |
moron All American 34183 Posts user info edit post |
^^^ the 2nd code is obviously better but i can't see many scenarios where it matters that much.
^^ that's interesting, the environment i work in doesn't develop any apps like that, but did they not take input from the different groups when designing or did those issues just stay under the radar until implementation?
[Edited on February 13, 2017 at 6:51 PM. Reason : ] 2/13/2017 6:50:54 PM |
CaelNCSU All American 7132 Posts user info edit post |
We had an obstinate architect, most of the issues were pointed conceptually out before we even went into production. It took a few months of fires and scrambling for him to leave and the political capital generated to fix it. Someone above my pay grade had convinced people the new #webscale Java $y$tem would be way better. Since it isn't we had to dismantle it and under the cover of existing work rebuild almost all of it.
Good times. 2/13/2017 7:18:07 PM |
FroshKiller All American 51913 Posts user info edit post |
moron said:
Quote : | "the 2nd code is obviously better but i can't see many scenarios where it matters that much." |
Clear your mind of all architectural concerns. Never mind the memory allocated for the utility class's members, never mind the overhead of instantiating the class just to call that function.
You have a sensitive value, like the combination to the Inception safe in your mind where you keep the memory of seeing your dad's dick in the shower. Maybe it's the answer to your security question.
The calling code wants to show that you have a value entered without revealing what the value is. What will it render? That is up to me, the stupidest function. "Gimme the combination, guv," I chortle. "I won't do nuffink wiv it."
Why do I need to know the combination at all? Why should the calling code give it to me?
Meditate on this until you are enlightened.
[Edited on February 14, 2017 at 6:06 AM. Reason : ...]2/14/2017 6:05:36 AM |
aaronburro Sup, B 53136 Posts user info edit post |
Quote : | "But it's really stupid in VB. It's an instance method, so every instance of the utility class allocates memory for that local variable MaskedValue. You know, the string that will only ever be an empty string or eight asterisks? There's no reason those shouldn't be constants, and if they can be constants, the method can be declared Shared." |
If you're worried about performance, using VB at all is a dealbreaker from the beginning. You're. Just putting lipstick on a pig at this point 2/16/2017 12:42:49 AM |
aaronburro Sup, B 53136 Posts user info edit post |
In the files of "terminally stupid," the server guys are now basically refusing to add new fields to our XML schemas for as yet unknown reasons. We have a "Notes" field in the current schema, which is an array of Note objects. Each Note has a Note Type property (basically an enum) on it and which takes an array of strings for the actual "note." Whenever they want to add a new field, they add a new value to the NoteType enum, and it gets added into the Notes property. BRILLIANT!
So, let's review what we currently have in this Notes property now... Comments... Always a single string. OK, odd, but whatever Confirm Comments... Another single string. Not getting better IsConfirmed... Fuck, really? A boolean value? Damnit Manager... ID and Name, pipe-delimited? Fuck off, assholes, I gotta parse this shit all over the app now.
Because, of course we didn't write a proper converter at the server boundary in the UI portion of the app. No, we pass the server's Notes model all through the application. And because it's an array, there's all kinds of fun in making sure you don't put the same "note" in there twice, so let's put that identical logic in 6 or 7 different code files...
Guess what the latest feature we are adding to the application is? If you guessed "actual notes which are related to this business object," then you win $5 lafta bux. As a bonus, guess how we are gonna pass those Notes between the UI and server? Are we gonna make a separate XML message for Note retrieval and updates? Fuck no, you've got a perfectly good Notes field right there on the business object! Let's just copy 500 lines of code from our business object's CRUD service so we can load up the whole business object, just to get the Notes! Oh, and when we want to add a new note, we'll add it to the new entry in the Notes array and just pass the whole business object back to the server process. Do the notes from this new feature get manipulated on the normal CRUD screens? Fuck no, they go through a completely different and purpose-built Notes screen. But, we'll get them in our regular XML objects, and probably be required to persist them in all of our CRUD actions, on multiple screens which don't give a fuck about them.
When I asked why we weren't bothering to write a proper XML message for the new notes feature (I gave up on getting fields added to the BO schema), I was told "this is a low priority feature compared to other stuff, and we don't have time." But I guess they have time to go through the CRUD service points and make sure those don't overwrite the new notes feature... Like I said: terminally stupid.] 2/22/2017 11:36:03 PM |
Lionheart I'm Eggscellent 12776 Posts user info edit post |
Interviewing a software engineer candidate today. Talks about UI/UX experience and designing web pages. Mentions he designed his website portfolio.
I look up his website. Website talks about his services for hire in web design. Website tagline "Coded by & Designed by "
Open developer console to inspect and see what's under the hood. Meta data points to a free theme bootstrap theme. Okay maybe he used it as a base and changed it a bunch. Pull up the theme, it's exactly the same, down to some of the base content with matching poor English.
Smdh. Were does my manager find these guys. 2/24/2017 3:51:11 PM |
aaronburro Sup, B 53136 Posts user info edit post |
Did the guy just not expect you to check? That's like the first thing I look at if someone gives mkeva URL sample of their work on a resume, and I'm a damn desktop dev. Wtf? 2/24/2017 11:15:47 PM |
OmarBadu zidik 25073 Posts user info edit post |
https://medium.com/neosavvy-labs/the-engineers-dilemma-334de2ceb4b7#.1btjq8941 3/1/2017 10:58:04 AM |
qntmfred retired 40806 Posts user info edit post |
^^^
a guy I interviewed a while ago presented me his portfolio as a front-end developer. behold.
http://frontendken.com 3/1/2017 2:40:27 PM |
synapse play so hard 60940 Posts user info edit post |
^ that's pretty great 3/1/2017 3:55:34 PM |
Lionheart I'm Eggscellent 12776 Posts user info edit post |
^^ Lol so many unnecessary divs 3/2/2017 8:34:23 AM |
aaronburro Sup, B 53136 Posts user info edit post |
I don't understand how someone can keep his job after repeatedly making changes to code that he doesn't understand, without asking anyone, and without it getting it reviewed whatsoever, all while introducing numerous bugs and crashes as a result. He's been repeatedly told not to do that, with managers and managers' managers CCed, and he still does it. I just don't get it. 3/31/2017 12:17:15 AM |
moron All American 34183 Posts user info edit post |
^^^^ he has a patent that seems legit, looks like his background is in physics/EE, weird he's trying to get a job doing front end work... 4/3/2017 1:40:45 AM |
Talage All American 5094 Posts user info edit post |
^Probably figured out kids 3 years out of college were getting paid more than him to make Angular apps
[Edited on April 3, 2017 at 8:01 AM. Reason : .] 4/3/2017 7:59:19 AM |
aaronburro Sup, B 53136 Posts user info edit post |
Hey, here's a great idea! One user who is being onboarded onto the system doesn't like some of the color choices and placement of certain fields on a screen, so let's do a 2 month redesign of the whole view for that screen for this one user, ignoring all of the other users' use cases.
This guy must have some serious blackmail on somebody high up. Every dev on this project, and the dev manager, has said "fuck this guy," and somehow we are still being forced to do this asinine project.
[Edited on April 4, 2017 at 12:49 AM. Reason : ] 4/4/2017 12:49:10 AM |
qntmfred retired 40806 Posts user info edit post |
Who hardcodes the same start/end times in 2 different places in the same codebase 4/12/2017 6:57:10 PM |
aaronburro Sup, B 53136 Posts user info edit post |
So, you want a context menu item (WPF) which shows which item is currently selected... I got it! Do a command which passes the context menu item as the command parameter and set the IsChecked property in the command! 4/19/2017 9:42:45 PM |