This was a nice article, but I’m not sure the title is representative of its contents. I think the first (Keep your users in the loop, always. Do not go build in isolation) or second to last (A user's workflow is everything ) bullet the author uses for their summary is findings to be more enlightening and representative.
Internal tools definitely require a close relationship with some set of users to really validate what’s being worked on.
It’s just too easy for teams to make unused internal tools. The feedback loop is generally just not there initially. You really have to go and find some users. In this way it’s similar to pre-seed stage startup life.
Code review is too late for most automated analysis (at the level of: "parameter isn't validated" as seen in the screenshot), it should ideally be done as a compiler/lint check in the IDE, and at worst as a git pre-commit hook.
In most cases it's not worth sending a code review if there is automated feedback which can and should be addressed before a human sees it. It streamlines the reviews for reviewers, and gives new contributors a much better experience as they have less feedback to address, and more confidence that their code is correct.
Your comment is more true today than it was back then, not that I disagree with you posting it. Back then linters were a twinkle in the hopeful eye of software devs. Now they're battle hardened.
It seems like autofixing linters got popular about 10 years ago? That was when it hit my radar at least, but before that I wasn't really a software dev. Whenever it happened that was a quantum jump in usability.
It's a 2018 paper, but definitely: it feels like something that's come to the forefront in the past 6/7 years and I don't think people are leveraging it enough.
It's so nice to be able to write a compiler/lint rule with a quick fix and then see it catch both my own mistakes, and potentially remove a concern/checkbox from the code review template
There's nothing more frustrating than a stupid machine telling me it knows better when it doesn't. I used to work on a team where the build defaulted to fail if something wasn't used and debugging was a fucking nightmare because the moment you comment out a block of code there's a cascade of warnings into errors that is just never ending (it was typescript so it leaked all the way back to module definition). I had to piss away some time to write a script to turn a bunch of the rules off and then remember to re-enable them later or I'd break the build by breaking someone's OCD.
Well, don't turn warnings into errors. Doubly so on your development environment. That's not a good reason for not running a linter while developing.
But, of course, if the decision was out of your hands, people that do that are usually the same that enable all linter rules. Neither decision makes for a good development practice.
One automated thing I've been really wanting to add to our code review process is copied code detection, where a piece of code is very similar to code somewhere else in the product (though likely not part of the current review).
Obviously there's cases where this is code smell, but plenty of times it isn't. It's not something that you would want to block shipping. But if you do want to ship code like this, you should do so with the reviewer(s) fully seeing where it came from, to make sure everyone agrees that's the best way.
No one has implemented a bot for us that would add such comment for use but I do think it would be a huge win.
Sonarqube has, among other things, code duplication detection, where it detects very similar, but slightly different blocks of code.
It's possible to wire things up so that it runs when you open a merge request and notifies you via email the results.
It's not a silver bullet though.
It also has a linter plugin for vscode (and possibly other editors) that DID NOT work well, atleast the last time I checked which was before February this year. Just thought you should know, incase you decided to just use the linter.
This is particularly true if the “users” aren’t the ones who are signing the cheques. Sometimes shiny stuff that looks good in a product demo or on the trade show floor is what it takes to actually move units.
The author is atleast referring to those rants as "angry mails" he got.
I think these automated CI systems is a losing battle. It makes the build chain to complex. There is too much corner cases that gives false positives unless you keep it dead simple, like eg. enabling all warnings are errors or something in gcc.
One of many things I learned from writing software just for myself is that I'm just about as bad as anybody at figuring out what I really want, even when I'm talking to myself. I've even had one or two cases where I ignored a feature I asked myself for, and much later realized: Hey, I could actually use that. The worst is asking myself, "How many times do I have to ask for this before you quit procrastinating and just get it done???" I'm not sure which of me is the bigger jerk.
Oh hey its me. I've done some painstaking work to add a feature (hell, even just an excel macro that at the time seemed useful) and realize like 9 months later I've used the feature a whopping 3 times.
The challenge there is when people start using your personal project. Yes, you remain in control and you remain the primary user. But… now regression and features become a much greater concern because the last thing you want to do is harm other people even if they are only a secondary audience. As the project grows this becomes the most pressing concern regardless of who is the primary user.
That begs the question: Why bother growing the application beyond the smallest set of explicit use cases? When you are the primary user AND the only use environment or input samples are written by you life is simple. The moment you must analyze something not written by you, even if this usage is only for you, the problem cases blossom. If your application refuses to solve for those cases then you need to add more features or use a different application.
Those two scenarios seem to feed each other which becomes evident by traffic or usage numbers as you pull your hair out keeping up with some hobby application.
Sometimes it's wise to ignore what you want. So many times I started a project only to end up with 3 libraries and a custom build system. It's like I can't help myself. It got to the point I was too embarrassed to publish these things on GitHub.
When you ask people to imagine a feature, they're going to imagine the absolute perfect version of the feature, for them personally. A feature that requires no effort to set up or use, provides exactly the information or functionality they want, and never gets in the way of anything else.
Everyone takes for granted how smooth their own workflow is to them, both because they're already used to it, and because they sunk effort into it to make it smooth (via learning or planning), which has probably been forgotten. So, people just take for granted that new features will maintain that acquired smoothness --- unfortunately, they usually don't.
As the author found out, most of the work in building features is often not in the "raw functionality" of the feature, but rather in making something that performs its functions while also not costing the user significant extra mental or physical effort to use.
Nice post. I liked this take away. "Users say things for a reason, but there may be more to it than face value."
Theres often more to what a human says than face value. The key is to always be asking questions, always ask why, multiple times. Ask questions until you feel like you're on the edge of pissing someone off.
Often, a good bit of time up front can get to a few outcomes which save you a massive headache.
1) You understand the feature so well, you're ready to go and know it will be used.
2) The REAL ask was something totally different, and now you know what you need to do (nor not in some cases, sometimes its training, using the product properly/as intended etc).
You're also going to be giving the requester the space to fully explain themselves, and sometimes they can talk themselves round as well. At the end of the day everyones a winner when we ask more questions and listen.
Not just that. If the feature is given in an usable or other poor form. They won't use it even when they have it right there. May be its not very obvious, or complicated, or too time consuming. Design makes all the difference.
If you give them something they never needed or asked for, but it's so obvious and simple to use, they will use the hell out if it.
It has a "Design controversies" section that's very relevant to today:
> Complaints also surfaced about the taillights on 1958-model Edsel station wagons. The lenses were boomerang-shaped and placed in a reverse fashion. At a distance, they appeared as arrows pointed in the opposite direction of the turn being made. When the left turn signal flashed, its arrow shape pointed right, and vice versa
I once spent a week working on a fairly complex feature for a product that the users were demanding almost daily updates on. I delivered it and, by coincidence, happened to be where the users were a couple of weeks later and I stopped by to say hello and saw that the user who had been asking for the feature every day was still using the product the "old way". I asked why and he didn't seem to follow what I meant, so I reached over and showed him the feature that he had been demanding I add and he said, "oh, wow, that's awesome, that's going to be such a huge timesaver for us!"
If quantum scientists thought the slit experiment was exciting, they should study IT user preferences and be amazed how depending on the mode of communication/observation, customers will both scrutinize every letter you write while simultaneously not reading it at all, will know every wrong pixel of your UI but not know where the button for "Thing" (labeled "Thing") is, and how anything you make is somehow the best worst average thing they've ever seen.
If you're ever user facing it's a harsh but quick lesson that you can't really count on any users to follow any real pattern. Different persons latch onto different things, with adamant proponents and opponents of everything with a huge swatch of grey shades in-between. At a certain point you just need to decide when the "grey" is no longer grey for you on a particular subject and start to optimize for the part that cares while checking why the grey part isn't as interested.
A lot of conversations with clients I have are with those in the grey territory, where they don't quite know what they want but they know they want it. Often times, they're more looking for a reference architecture and something to compare their current processes/workflows to, and this usually is pretty simple to work with. Those that are proponents of a feature N are typically vocal and picky, but the feedback tends to be pretty good and the guidance is clear on how they envision it, since there's a clear workflow on their side a lot of times that they want to optimize. Opponents of feature N typically bring out the edge cases and demand a solution, and are equally, if not more vocal than the proponents.
It's really a tricky thing, and it's never really clear which is going to be "best" for users/the dev team.
I've had something similar happen to me, and quickly learned not to assume that your customer POC will effectively relay information to the end users in their organization. They were pinging us constantly about a new feature because it was on their list of things to ask about. Once we told them it was done, they crossed it off their list and we never heard about it again until months later discovered by a chance interaction that none of the product users in the organization even knew we had added the feature.
The wonders of digital transformation.
One of my biggest insights here was that digital transformation is not only the technical upgrade or simplicity of implementation but rather the cultural implementation i.e., process re-development and re-training.
This is why changelogs and release notes are not optional or tucked away in a dark corner. And users who request features need to be notified (actively, specifically) that something they requested or a bug they hit was resolved or addressed.
I know, that's a lot of work. But what's the point of fixing things if you never tell someone it's fixed.
We've sent release notes our for a while but no one ever read them.
Now we do showcases of the feature so people have no choice but to see what new features are coming.
changelogs and release notes don't get read. unless you're sending personal emails to the users who requested the feature, the experience in the essay here is the only way: make it automatic or turned on by default.
and if it's not good enough to be automatic or enabled by default, then keep iterating until it is.
They're a bad way to communicate specifics because they're literally a long list of changes, most of which are boring/irrelevant to most people.
If you're releasing new features you need more ceremony. Maybe an email with targeted specifics, or at least a section on your website which highlights big important new features.
That's great advice, but it's untrue that nobody reads changelogs.
I read them religiously for software I'm passionate about as a user, and when I solo'd a product for a decade I was regularly surprised how familiar some of my customers were with mine (most often when they had dedicated IT resources or were similarly small boutique outfits themselves). I've also managed large, custom enterprise projects where subject matter experts on the other end relied on them (in addition to other channels of communication).
What drives me nuts is how some companies decided to water them down. e.g. Windows Update's long list of "security related update" where you have to google KB's to find out what they are, and another company that just always puts in "various fixes and improvements".
I've started collecting screenshots of app updates that are simply "bug fixes and performance improvements" because it's such a joke at this point. What bugs? How much performance improvement? Did you also nuke one of my favorite features while you were at it, or require other actions of me that I wasn't intending to perform? Who knows? Guess I'll roll the dice once again...
When I read release notes like that I immediately assume malice. I don't believe that the information is not available or that the devs are too lazy to bullet point _at least_ the major changes or vulnerabilities fixed. I think this is generally an excuse to slip in tracking/etc without resistance.
Nah, it seems more likely that the mgmt. saw the list of bugs and said "don't admit to those!" and the performance improvements ... " Don't say we used to use a stupid O(n^3) algorithm!
From my experience, it's probably tens of bugs where each of them happened to less than 0.01% of customers, and requires a overly detailed explanation for anyone who didn't have first-hand experience with it.
I wish software did something more like video games. Well-designed video games will notice that there's a skill you're not using when you should be and show hints on-screen about using it, e.g. press L1 to change weapons, R2 to take cover.
I’m not so sure. It’s mildly irritating getting numerous pop ups of “hey, look over here at this thing we added” even when permanently dismissible.
Tracking a user and letting them know that we know they haven’t ever used feature X is likely to just give them the creeps.
In video games you are in “play” mode, and very aware you’re being tracked, judged, awarded points etc. In software that’s often less clear and (from certain behemoths) deliberately so. You’re also likely trying to achieve a task, rather than have fun. I personally would find it irritating if not downright invasive if I hadn’t explicitly agreed to something clearer and more explicit than a cookie warning.
To clarify, was he not aware that the new feature had already been released? Or did he think the "old way" was the new feature (and that he'd simply been blocked before), thus suggesting that the urgency of his ticket was unnecessary?
Sometimes I wonder if software is becoming worse because logging is coming better. We have so much data about problems that users are having, feedback they're providing, etc. Perhaps following the mass of people is the root cause of software's constant and worse UI changes.
My favorite thing about their text editor is that it will delete all of your changes with no option for recovery if you accidentally hit the escape key. I also like how this has been an open issue for many years on Jira, but they refuse to change it for some reason (or at least that's the state of it the last I checked about a year ago. Thankfully, I don't have to use any Atlassian products anymore.)
> Turns out there were a few hiccups: everyone involved in that project we wanted to use had left the company, we had no idea how to build the source code, it had something like 500,000 lines of code, and the one person we found that knew anything about the project was 13 hours ahead and stopped replying to our emails.
When you don't talk to users this is what you end up with.
Before the launch of the XBOX 360, the company I worked for was one of their suppliers, and without going into enough detail to make me identifiable, the management of our two companies had arrived at sort of a stalemate: We didn't want to tell them exactly how our algorithms worked, and they didn't want to tell us exactly what they were doing with them-- think of it like a data compressor where, we don't want them to know the exact compression algo, and they don't want us to have their data.
So, somehow, It is arrived at that a website will be created that encodes MS's proprietary data, but doesn't store it, but also our algorithm is implemented server side, so there's no leakage of proprietary stuff.
A month later, the app is done and tested and I'm decoding data from the website on real hardware. I move on to the next project.
Three years later, the Xbox 360 is out, I decide I'm tired of filling out reimbursement forms for Heroku and its got to be a security risk with no updates in 3 years... so I take a look at the apps stats to see if its feasible to shut it down--exactly zero users. Nobody ever attempted to use it, not even once.
Ironically and unknown to me, the source code had been lost in a freak accident and when I deleted the Heroku account that was the only copy of the source left.
Even worse, a year later someone claimed to have a use for the app and where was it please? And I had to explain we no longer had the source. I remember a very long e-mail about how irresponsible we were.
If they were that serious about security-- the chips we made also implemented this same compression algorithm. It would have been trivial to hook one up to an arduino and feed it the data you wanted to encode. I assume someone realized this, or they never really had a need to encode their own data (we provided a extensive library of encoded data).
I strenuously disagreed with the business justification for keeping all this stuff secret. But it was my job to respect those decisions.
It was a lot of fun writing the (rails) app itself.
The worst programming experience of my life related to lost source code.
I was working for a place that had a service running from a Java app that was customized for each customer, about 200 copies of roughly the same app. There was source control at some point, and when a new customer was being on boarded they’d just make the customizations they required, compile the app, and deploy it.
By the time I worked there (years later), all source code had been lost, and I was tasked with creating a CI/CD system that included managing these apps (they’d now decided they needed to be maintained).
For each one I had to decompile the whole thing, rewrite the code into a human readable format, redeploy and test it. They were filled with all sorts of horrible anti-patterns too, like hard coded file paths, and some of them were only used once a year (but for an absolutely business critical process).
About half way through we had a major data center failure that meant we had to do a failover, which of course broke most of these apps with all their hard coded configuration. So instead of having months to work through all of this garbage, I was asked to get them all working immediately.
I got them all working in 3 days, which I thought was quite a monumental accomplishment. But my CEO was very dissatisfied that it took so long. I quit a couple weeks later, and still almost regret putting so much effort in to saving them. A friend of mine still works there and apparently all of these applications are in exactly the same state as I left them.
Yeah I was definitely right to quit, my career has been pretty great since then.
But I did get a lot out of the few years I worked there, even though a lot of it sucked. It was my first proper job and they’d basically let me work on anything I wanted to, even though I was incredibly green and was just figuring it all out as I went. I definitely fit a lot more experience and learning into those years than you’d reasonably expect a person to. I think a lot of my success today came from turning their incompetence into opportunities.
I be also had a job early in my career where I was basically allowed to work on anything that interests me and 20 years later I’m still relying on that experience.
Maybe this is something every junior should do - try a bit of everything and see what you like.
That's why I think a good consulting agency can be a great first place to work. Lots of projects, hopefully different technologies, perhaps international clients with travel. Then once you know what you like and specialize a bit in it, it's easier to step to some product company as a senior.
Plus, in my experience consulting companies are more focused in employee well-being as it's their only asset.
> There's a certain personality type that will never appreciate or reward hard work.
Now, how would someone figure out these personality types ahead of time? Any red flags to detect people or workplaces to avoid in a professional capacity?
Ask them flatout how they reward initiative and accomplishment. If they start fumbling, there's your answer. If they don't, ask them for a concrete example. If that's when they struggle, there's your answer.
1. "...Able to work under pressure and meet deadlines.."
PASS !
2. "I(boss) coded the first version..."
50% of the time it means:
Your solutions or design decision will never be "as good as his" and you will forever hear "I did it like this and that. It should be fast to implement xyz"
Hilarious. Why didn't you refactor the customizations into a config file, and just deploy a single jar though? If you went through the effort of rewriting the entire thing!
The issue I found when I was first looking at it was they were all a little bit different in random, and confounding ways. Also, whatever the “base version” of the application was had been undergoing development over the years when all these forks were being made.
Looking back on it, that likely would have been the best approach. But at the time the complexity of designing something like that was a bit beyond me.
Instead the OP fed the old version into a tool (Disassembler) which spat out terrible source code, worse than the original with no comments and bad variable names.
This was the only way to get source at all.
Then they made the disassembled source compile in a really nice way.
Finally the boss asked them to make huge changes to this horrible source with time pressure.
A lot of the work would have been roughly equivalent to trying to de-minify some JS.
With a modern IDE the task would have been a lot easier. I don’t know if Eclipse had refactoring assistance built into back then, but if it did, I’d never even heard of the idea. I was sitting on not much more than a year of programming experience at the time.
Textually comparing disassembled code variants can be complicated because the disassembler might/will generate different names for locals.
Because of that, a better approach might be to compare the byte codes of the variants first to find out in what classes the variants differ.
Then treat the different class files as source code until you need to change any of them (so, variant 1 has foo1.class, bar.class, and baz.class, variant 2 has foo.class, bar2.class and baz.class, etc). Don’t immediately try to clean up their code, but ‘just’ try to figure out what they are doing (for many of them, that, hopefully, can be done from function names)
On the topic of lost source code... we had a few blessed binaries that were vital to building System 8 and System 9 at Apple. There was a single build machine that could generate these binaries from other object code but the source was long gone. Oh please oh please old Quadra 700, don't give out on us! Those days are over right? Surely nothing like that is happening with OSX...
I can't edit my post anymore-- before someone realizes my mistake, it was the XBox One, not the 360. Rails barely existed at the time of the XBox 360 development.
Thanks for updating! I was a little confused since Heroku wasn’t around before the 2005 launch of the Xbox 360, but figured it was shorthand for something else.
Given the Xbox One SOC had a lot more security in mind, I could see how Microsoft was more cautious about these things. [1]
Just a lapse of memory and thanks for the benefit of the doubt. Another commenter mentioned turbolinks and I was like "whoooaaaa yes I used that and this timeline doesn't line up at all." This lead to a long internal discussion about when exactly did I play Bioshock and does that line up with my memories :-)
I guess I don't mind talking about it so much-- we made a sub $1 component that could compress certain specific waveforms and play them back-- the trick was that they were highly structured, so the compressed data basically just parameterized the silicon in what might be considered to be essentially an assembly instruction-- frequency, carrier wave, data to be sent, etc. The chip then would generate the signal and you could shove it out the electromagnetic radiator of choice with a little amplification a diode and couple of resistors. The problem with these signals was they required very precise timing-- they weren't super complex, but not something a general CPU could handle-- the variability in the timing was too high.
Now yes, you could use a general purpose DAC and an amp and generate the signals, but we sold you a turnkey thing-- with 10 lines of code you could be transmitting signals and the whole thing only use a few kb of ram.
It wasn't super high tech, but our value add was high. I'd say most of the major electronics companies used our chips at one time or another.
Yea, we were a consumer electronics company that mostly was subcontracted out to make components or complete hardware. I remember working on products for Denon, Crestron, Roku, Samsung, LG, Direct TV, Microsoft, HP, Nintendo, Sony and Audiovox (and their subsidiaries--Monster etc), and in Europe, One For All brand. It was honestly pretty exciting.
Regarding web services, like I said, we had a library of these waveforms and that was our cash cow-- you got the chips for only a few cents over cost. You got the API that operated them for free, but access to out database cost a fair bit.
Ah, so I'd guess you were producing some chip that generated IR signals to control various consumer electronics devices, and the library is a library of control commands of thousands of devices of different manufacturers.
Basically what you need to build a universal remote control, or a remote control for a specific device that includes controlling capabilities for other manufacturers' devices.
I'm pretty sure about that, especially since One For All is a brand dedicated to universal remotes.
If I had to take another guess, I would even nail it down on him having been employed by a company called Universal Electronics, which produced a series of universal remotes called "JP1 remotes" in hardware hacker circles (see for example http://www.hifi-remote.com/files/help/The%20WHAT%20and%20WHY...) and also acted as an OEM for a lot of other companies, so their tech could be found in various remotes of different brands.
[edit] I was slightly wrong. He was working for Zilog (which sold their universal remote business to Universal Electronics Inc. in 2009 however) and probably involved with a cool-named product called "Crimzon RC Blaster": https://www.zilog.com/docs/ir/PB0171.pdf
The description sounds like software defined radio. A CPU's frequency jitter doesn't matter at all for haptic feedback. Presumably it's not for WiFi, as there are plenty of cheap well-tested WiFi chipsets, so maybe for wireless controllers.
Edit: I was wrong about the frequency range, a sibling comment to yours mentions IR, not radio. Though, their mention of "radiator of choice" sounds like this same chip (or related chip) could be fed into an RF modulator/demodulator to build a software defined radio.
Slightly frustrated to read this, because this is user research 101! It's really impressive when someone independently discovers practices from an outside discipline, just by observation and inference. However, somebody could have saved this poor guy a lot of frustration by not forcing him to develop a product design methodology from first principles.
For this specific case (product discovery interviews) take a look at Interviewing Users by Steve Portigal, and Validating Product Ideas by Tomer Sharon.
I found "Don't Make Me Think" by Steve Krug to be a helpful guide. As an engineer who was shy to approach product design, I felt the language really helped demystify things.
They were an intern, but I think it leads to a bigger point I was thinking about as I was reading this:
In every org I’ve been in, we’ve had interns do these kinds of things: build big intrusive things that suck and no one uses. The problem obviously isn’t the interns. It’s the projects we give them, which are meant to be basically “throw-awayable”, and the complete lack of actual guidance and oversight.
Why are tech companies so bad at actually mentoring interns? They _should_ have had someone teaching them about user experience 101, and they completely let them flounder. How are we supposed to continue to grow and evolve as an industry if we make make every neue klasse start from scratch?
The funner one is unique to enterprise developers. Begged to implement a feature to the enterprise software, the development team puts in a hell of a lot of hours to get this time sensitive feature into the production. Then, out of nowhere, a manager of some import informs everyone that they cannot use that feature as its "against best practices" or some other language to that effect. Bonus points if said manager was on the email chain about the feature and its progress.
What do you do at this point? People complain about meetings saying that "this could have been an email" (including me). But I believe some people just don't read email/chat/jira comments. Maybe they're busy or just don't care at all, who knows. How else would you get your point across?
I think people don't really follow meetings either. We had a ton of going back to the transcripts to prove topics have been discussed.
There is no magic bullet, if someone has the power to make decisions, you are always at the risk of having them change course at any point in time. The only think you can do is deeply convince them it's in their interest you succeed.
This is relevant perhaps 10% of the time. The other 90%, the devs have absolutely no idea how to actually perform the task the user of the software is trying to do, don't talk to customers, don't dogfood it, often don't even understand the industry, and the result is a horrible UI which forces people to severely adjust their existing processes to fit the software. Then if course the devs complain about "the stupid users." To this day 99% of address forms expect me to find my state from a drop down list of 50 entries plus DC, Puerto Rico, Guam, etc. instead of simply typing in the two letter abbreviation.
Not to mention international address forms which expect you to scroll all the way to U for Brits and Americans. I understand the the alphabetical listing is the most internally-consistent way to display to the users, but either putting duplicate entries for the most popular countries at the top of the list or providing a text field that suggests the normalized country as you type ought to be the go-to, not a purely alphabetic dropdown menu.
I moved from engineering to product management precisely because I realized that the problem of "what should be built" is often harder than building the thing.
Asking users what features they want is pretty much not fair - because most people don't have the skills to think through and answer that question, nor is it their job to do it. It's like asking a novel reader what they'd like to see in the next chapter. It's a cop-out with guaranteed suboptimal outcome.
Obviously product management is half art half science but in a nutshell, much better than asking an individual what features they want would be asking them - especially on a senior level - what problems they have and what keeps them up at night. Getting an understanding of that and then thinking about how those problems/risks can be addressed by your system is a much better starting point.
The reason I say that it's important to partner with your users on the senior level is the difference in perspective on the class of problems they want to tackle.
For example I used to work on a trading platform. If I went to my heaviest users and asked them what their problems were, they would probably say "I do 1000 trades a day, and I have to tweak each one manually - can you make that process faster" and maybe even have an idea of what that could look like. So let's say I did that and shaved a second off each trade handling so my user is happy cuz I saved them 16 minutes a day. Sounds like a job well done.
But if instead (or in addition) I talked to their boss, I might hear a very different story. Eg: "we do 1000 trades here every day, but 900 of them are straight forward. I wish I could automate those so trader can focus on the 100 complicated ones. But instead, he's so busy doing the 1000 trades that a lot of them get fucked up especially the complex ones."
That's a major change of perspective, from optimizing an existing workflow to optimizing the entire operation. The implementation is quite different - one is a UI optimization and the other is establishing some sort of automation capability that can be extended to all my clients over time. One may be doable with the team you have, one may require standing up a new group, etc.
At the end, the end user is happy (they get to do 10% of their previous load but this is the high value 10% they really want to focus on.) The key point is that neither the user nor their boss could tell me exactly what to build, but the high level perspective allowed me to understand their problem in a deep way and figure out a scalable solution for them and other clients.
Anyway that's just an example but yeah, your users can't tell you what to build and yeah you need a good product manager - or someone who can play that role well.
>Asking users what features they want is pretty much not fair - because most people don't have the skills to think through and answer that question, nor is it their job to do it.
100%, Usually early in the "project discussion" I try to boil it down to just ONE CORE PROBLEM they have.
For example:
If you had a magic wand that could generate ANY SOFTWARE to SOLVE ANY problem in your business (but restricted to ONE problem). What would that problem/solution be ?
From there it's usually easier to generate a feature-list(requirements) as long as you solve the damn core problem :P
They wrote a bunch of them (StyleCop among others) for C#. And Intellisense which relies on being able to analyze code all kinds of ways. I find it hard to believe they didn't.
The automatic code analysis tools. Sure they existed, but they need to fit into a workflow and get approval for use (which takes about ten years in enterprise these days).
I find it's usually release with the minimum necessary features first. Once they digest those, then add on the next set based on feedback. The more incremental the better. But do keep likely future features in mind, such as leaving space in the tool-bar etc. Certain things are hard to retrofit after the fact.
225 comments
[ 4.6 ms ] story [ 188 ms ] threadInternal tools definitely require a close relationship with some set of users to really validate what’s being worked on. It’s just too easy for teams to make unused internal tools. The feedback loop is generally just not there initially. You really have to go and find some users. In this way it’s similar to pre-seed stage startup life.
Code review is too late for most automated analysis (at the level of: "parameter isn't validated" as seen in the screenshot), it should ideally be done as a compiler/lint check in the IDE, and at worst as a git pre-commit hook.
In most cases it's not worth sending a code review if there is automated feedback which can and should be addressed before a human sees it. It streamlines the reviews for reviewers, and gives new contributors a much better experience as they have less feedback to address, and more confidence that their code is correct.
It's so nice to be able to write a compiler/lint rule with a quick fix and then see it catch both my own mistakes, and potentially remove a concern/checkbox from the code review template
But, of course, if the decision was out of your hands, people that do that are usually the same that enable all linter rules. Neither decision makes for a good development practice.
> implaying
and
> srsbsns
to toggle it off/on.
Obviously there's cases where this is code smell, but plenty of times it isn't. It's not something that you would want to block shipping. But if you do want to ship code like this, you should do so with the reviewer(s) fully seeing where it came from, to make sure everyone agrees that's the best way.
No one has implemented a bot for us that would add such comment for use but I do think it would be a huge win.
It's possible to wire things up so that it runs when you open a merge request and notifies you via email the results.
It's not a silver bullet though.
It also has a linter plugin for vscode (and possibly other editors) that DID NOT work well, atleast the last time I checked which was before February this year. Just thought you should know, incase you decided to just use the linter.
https://www.sonarqube.org/
I think these automated CI systems is a losing battle. It makes the build chain to complex. There is too much corner cases that gives false positives unless you keep it dead simple, like eg. enabling all warnings are errors or something in gcc.
That begs the question: Why bother growing the application beyond the smallest set of explicit use cases? When you are the primary user AND the only use environment or input samples are written by you life is simple. The moment you must analyze something not written by you, even if this usage is only for you, the problem cases blossom. If your application refuses to solve for those cases then you need to add more features or use a different application.
Those two scenarios seem to feed each other which becomes evident by traffic or usage numbers as you pull your hair out keeping up with some hobby application.
Everyone takes for granted how smooth their own workflow is to them, both because they're already used to it, and because they sunk effort into it to make it smooth (via learning or planning), which has probably been forgotten. So, people just take for granted that new features will maintain that acquired smoothness --- unfortunately, they usually don't.
As the author found out, most of the work in building features is often not in the "raw functionality" of the feature, but rather in making something that performs its functions while also not costing the user significant extra mental or physical effort to use.
Theres often more to what a human says than face value. The key is to always be asking questions, always ask why, multiple times. Ask questions until you feel like you're on the edge of pissing someone off.
Often, a good bit of time up front can get to a few outcomes which save you a massive headache.
1) You understand the feature so well, you're ready to go and know it will be used. 2) The REAL ask was something totally different, and now you know what you need to do (nor not in some cases, sometimes its training, using the product properly/as intended etc).
You're also going to be giving the requester the space to fully explain themselves, and sometimes they can talk themselves round as well. At the end of the day everyones a winner when we ask more questions and listen.
https://simpsons.fandom.com/wiki/The_Homer
Not that all users are equal to Homer, but what they think they want and what they actually need are very different.
It's better to get more detail on the problem, then present a series of possible solutions to evaluate and iterate on.
If you give them something they never needed or asked for, but it's so obvious and simple to use, they will use the hell out if it.
> > It is a parody/exaggeration of the Edsel, a similarly disastrous automobile designed by Ford Motor Company.
Points to https://en.m.wikipedia.org/wiki/Edsel:
It has a "Design controversies" section that's very relevant to today:
> Complaints also surfaced about the taillights on 1958-model Edsel station wagons. The lenses were boomerang-shaped and placed in a reverse fashion. At a distance, they appeared as arrows pointed in the opposite direction of the turn being made. When the left turn signal flashed, its arrow shape pointed right, and vice versa
https://en.m.wikipedia.org/wiki/Edsel#/media/File%3A1958_Eds...
Why is it relevant? Related thread from 3 days ago about blinkers with the exact same design flaws , but in 2021: https://news.ycombinator.com/item?id=28661282
If you're ever user facing it's a harsh but quick lesson that you can't really count on any users to follow any real pattern. Different persons latch onto different things, with adamant proponents and opponents of everything with a huge swatch of grey shades in-between. At a certain point you just need to decide when the "grey" is no longer grey for you on a particular subject and start to optimize for the part that cares while checking why the grey part isn't as interested.
A lot of conversations with clients I have are with those in the grey territory, where they don't quite know what they want but they know they want it. Often times, they're more looking for a reference architecture and something to compare their current processes/workflows to, and this usually is pretty simple to work with. Those that are proponents of a feature N are typically vocal and picky, but the feedback tends to be pretty good and the guidance is clear on how they envision it, since there's a clear workflow on their side a lot of times that they want to optimize. Opponents of feature N typically bring out the edge cases and demand a solution, and are equally, if not more vocal than the proponents.
It's really a tricky thing, and it's never really clear which is going to be "best" for users/the dev team.
Users not knowing what they want but knowing that they want it is a useful phrase.
Nobody was yelling at anyone to actually use it.
I know, that's a lot of work. But what's the point of fixing things if you never tell someone it's fixed.
and if it's not good enough to be automatic or enabled by default, then keep iterating until it is.
They're a bad way to communicate specifics because they're literally a long list of changes, most of which are boring/irrelevant to most people.
If you're releasing new features you need more ceremony. Maybe an email with targeted specifics, or at least a section on your website which highlights big important new features.
I read them religiously for software I'm passionate about as a user, and when I solo'd a product for a decade I was regularly surprised how familiar some of my customers were with mine (most often when they had dedicated IT resources or were similarly small boutique outfits themselves). I've also managed large, custom enterprise projects where subject matter experts on the other end relied on them (in addition to other channels of communication).
What drives me nuts is how some companies decided to water them down. e.g. Windows Update's long list of "security related update" where you have to google KB's to find out what they are, and another company that just always puts in "various fixes and improvements".
I can't imagine writing an academic paper for any of the projects of similar complexity and general interest that I've worked on.
You don't need peer review for everything.
When you don't talk to users this is what you end up with.
So, somehow, It is arrived at that a website will be created that encodes MS's proprietary data, but doesn't store it, but also our algorithm is implemented server side, so there's no leakage of proprietary stuff.
A month later, the app is done and tested and I'm decoding data from the website on real hardware. I move on to the next project.
Three years later, the Xbox 360 is out, I decide I'm tired of filling out reimbursement forms for Heroku and its got to be a security risk with no updates in 3 years... so I take a look at the apps stats to see if its feasible to shut it down--exactly zero users. Nobody ever attempted to use it, not even once.
Ironically and unknown to me, the source code had been lost in a freak accident and when I deleted the Heroku account that was the only copy of the source left.
Even worse, a year later someone claimed to have a use for the app and where was it please? And I had to explain we no longer had the source. I remember a very long e-mail about how irresponsible we were.
If they were that serious about security-- the chips we made also implemented this same compression algorithm. It would have been trivial to hook one up to an arduino and feed it the data you wanted to encode. I assume someone realized this, or they never really had a need to encode their own data (we provided a extensive library of encoded data).
I strenuously disagreed with the business justification for keeping all this stuff secret. But it was my job to respect those decisions.
It was a lot of fun writing the (rails) app itself.
I was working for a place that had a service running from a Java app that was customized for each customer, about 200 copies of roughly the same app. There was source control at some point, and when a new customer was being on boarded they’d just make the customizations they required, compile the app, and deploy it.
By the time I worked there (years later), all source code had been lost, and I was tasked with creating a CI/CD system that included managing these apps (they’d now decided they needed to be maintained).
For each one I had to decompile the whole thing, rewrite the code into a human readable format, redeploy and test it. They were filled with all sorts of horrible anti-patterns too, like hard coded file paths, and some of them were only used once a year (but for an absolutely business critical process).
About half way through we had a major data center failure that meant we had to do a failover, which of course broke most of these apps with all their hard coded configuration. So instead of having months to work through all of this garbage, I was asked to get them all working immediately.
I got them all working in 3 days, which I thought was quite a monumental accomplishment. But my CEO was very dissatisfied that it took so long. I quit a couple weeks later, and still almost regret putting so much effort in to saving them. A friend of mine still works there and apparently all of these applications are in exactly the same state as I left them.
There's a certain personality type that will never appreciate or reward hard work.
But I did get a lot out of the few years I worked there, even though a lot of it sucked. It was my first proper job and they’d basically let me work on anything I wanted to, even though I was incredibly green and was just figuring it all out as I went. I definitely fit a lot more experience and learning into those years than you’d reasonably expect a person to. I think a lot of my success today came from turning their incompetence into opportunities.
Maybe this is something every junior should do - try a bit of everything and see what you like.
Plus, in my experience consulting companies are more focused in employee well-being as it's their only asset.
Now, how would someone figure out these personality types ahead of time? Any red flags to detect people or workplaces to avoid in a professional capacity?
PASS !
2. "I(boss) coded the first version..."
50% of the time it means:
Your solutions or design decision will never be "as good as his" and you will forever hear "I did it like this and that. It should be fast to implement xyz"
There's a book called "Dangerous Personalities" which takes a dive into practical psychology for these sorts of people.
Looking back on it, that likely would have been the best approach. But at the time the complexity of designing something like that was a bit beyond me.
Instead the OP fed the old version into a tool (Disassembler) which spat out terrible source code, worse than the original with no comments and bad variable names.
This was the only way to get source at all.
Then they made the disassembled source compile in a really nice way.
Finally the boss asked them to make huge changes to this horrible source with time pressure.
A lot of the work would have been roughly equivalent to trying to de-minify some JS.
With a modern IDE the task would have been a lot easier. I don’t know if Eclipse had refactoring assistance built into back then, but if it did, I’d never even heard of the idea. I was sitting on not much more than a year of programming experience at the time.
Hence why it had, and still keeps it, a Smalltalk like code navigation.
Because of that, a better approach might be to compare the byte codes of the variants first to find out in what classes the variants differ.
Then treat the different class files as source code until you need to change any of them (so, variant 1 has foo1.class, bar.class, and baz.class, variant 2 has foo.class, bar2.class and baz.class, etc). Don’t immediately try to clean up their code, but ‘just’ try to figure out what they are doing (for many of them, that, hopefully, can be done from function names)
Often there are gurus too and monks live in the caves next to the relics, trying to guard the sacred grounds and spreading the gospel.
Given the Xbox One SOC had a lot more security in mind, I could see how Microsoft was more cautious about these things. [1]
[1] https://m.youtube.com/watch?v=U7VwtOrwceo&feature=emb_title
I guess I don't mind talking about it so much-- we made a sub $1 component that could compress certain specific waveforms and play them back-- the trick was that they were highly structured, so the compressed data basically just parameterized the silicon in what might be considered to be essentially an assembly instruction-- frequency, carrier wave, data to be sent, etc. The chip then would generate the signal and you could shove it out the electromagnetic radiator of choice with a little amplification a diode and couple of resistors. The problem with these signals was they required very precise timing-- they weren't super complex, but not something a general CPU could handle-- the variability in the timing was too high.
Now yes, you could use a general purpose DAC and an amp and generate the signals, but we sold you a turnkey thing-- with 10 lines of code you could be transmitting signals and the whole thing only use a few kb of ram.
It wasn't super high tech, but our value add was high. I'd say most of the major electronics companies used our chips at one time or another.
Regarding web services, like I said, we had a library of these waveforms and that was our cash cow-- you got the chips for only a few cents over cost. You got the API that operated them for free, but access to out database cost a fair bit.
Basically what you need to build a universal remote control, or a remote control for a specific device that includes controlling capabilities for other manufacturers' devices.
If I had to take another guess, I would even nail it down on him having been employed by a company called Universal Electronics, which produced a series of universal remotes called "JP1 remotes" in hardware hacker circles (see for example http://www.hifi-remote.com/files/help/The%20WHAT%20and%20WHY...) and also acted as an OEM for a lot of other companies, so their tech could be found in various remotes of different brands.
[edit] I was slightly wrong. He was working for Zilog (which sold their universal remote business to Universal Electronics Inc. in 2009 however) and probably involved with a cool-named product called "Crimzon RC Blaster": https://www.zilog.com/docs/ir/PB0171.pdf
Edit: I was wrong about the frequency range, a sibling comment to yours mentions IR, not radio. Though, their mention of "radiator of choice" sounds like this same chip (or related chip) could be fed into an RF modulator/demodulator to build a software defined radio.
In every org I’ve been in, we’ve had interns do these kinds of things: build big intrusive things that suck and no one uses. The problem obviously isn’t the interns. It’s the projects we give them, which are meant to be basically “throw-awayable”, and the complete lack of actual guidance and oversight.
Why are tech companies so bad at actually mentoring interns? They _should_ have had someone teaching them about user experience 101, and they completely let them flounder. How are we supposed to continue to grow and evolve as an industry if we make make every neue klasse start from scratch?
There is no magic bullet, if someone has the power to make decisions, you are always at the risk of having them change course at any point in time. The only think you can do is deeply convince them it's in their interest you succeed.
Asking users what features they want is pretty much not fair - because most people don't have the skills to think through and answer that question, nor is it their job to do it. It's like asking a novel reader what they'd like to see in the next chapter. It's a cop-out with guaranteed suboptimal outcome.
Obviously product management is half art half science but in a nutshell, much better than asking an individual what features they want would be asking them - especially on a senior level - what problems they have and what keeps them up at night. Getting an understanding of that and then thinking about how those problems/risks can be addressed by your system is a much better starting point.
The reason I say that it's important to partner with your users on the senior level is the difference in perspective on the class of problems they want to tackle.
For example I used to work on a trading platform. If I went to my heaviest users and asked them what their problems were, they would probably say "I do 1000 trades a day, and I have to tweak each one manually - can you make that process faster" and maybe even have an idea of what that could look like. So let's say I did that and shaved a second off each trade handling so my user is happy cuz I saved them 16 minutes a day. Sounds like a job well done.
But if instead (or in addition) I talked to their boss, I might hear a very different story. Eg: "we do 1000 trades here every day, but 900 of them are straight forward. I wish I could automate those so trader can focus on the 100 complicated ones. But instead, he's so busy doing the 1000 trades that a lot of them get fucked up especially the complex ones."
That's a major change of perspective, from optimizing an existing workflow to optimizing the entire operation. The implementation is quite different - one is a UI optimization and the other is establishing some sort of automation capability that can be extended to all my clients over time. One may be doable with the team you have, one may require standing up a new group, etc.
At the end, the end user is happy (they get to do 10% of their previous load but this is the high value 10% they really want to focus on.) The key point is that neither the user nor their boss could tell me exactly what to build, but the high level perspective allowed me to understand their problem in a deep way and figure out a scalable solution for them and other clients.
Anyway that's just an example but yeah, your users can't tell you what to build and yeah you need a good product manager - or someone who can play that role well.
Automating a workflow is the best optimization from the users point of view.
I love this analogy.
100%, Usually early in the "project discussion" I try to boil it down to just ONE CORE PROBLEM they have.
For example: If you had a magic wand that could generate ANY SOFTWARE to SOLVE ANY problem in your business (but restricted to ONE problem). What would that problem/solution be ?
From there it's usually easier to generate a feature-list(requirements) as long as you solve the damn core problem :P
The automatic code analysis tools. Sure they existed, but they need to fit into a workflow and get approval for use (which takes about ten years in enterprise these days).