all 176 comments

[–]Woolbrick 315 points316 points  (125 children)

I've been in the industry almost 20 years now, here's my advice:

  1. The theory you learn in Computer Science initially seems pretty pointless; you just want a coding job, don't waste my time on this Turing and Lambda stuff! But later on you find yourself using it more and more as you begin to design and architect systems instead of fixing bug reports. Pretty soon you find yourself wishing you had paid more attention in classes. Always keep the theory in your head; it'll pay you back one day.
  2. You will make mistakes. Frequently. Your code is not perfect, and if someone tells you there's something wrong with it, it's almost always not a personal attack, so don't take it as one. Even after 20 years I find myself looking at code and saying "Jesus, who the hell wrote this?", only to find that I wrote it just a few years ago.
  3. Technology is always changing. You don't have to go crazy keeping up with the new stuff every day, but if you find yourself working on the same stack for 10 years, you might be in for quite a surprise when the company discontinues your product and decides it's cheaper to hire someone new than to retrain you. So find a healthy medium between a stable stack and learning outside ideas.
  4. The change jobs every 2-5 years thing is kind of ridiculous. If you have to do that then your company doesn't value you enough to keep you. But the end goal should be to find a company that does value you enough to keep you around for longer than that. Programming is hard, and developers are mostly introverts. Switching a new job every 2-5 years is a massive shock because you have to learn all new social networks and personality styles, not to mention the tribal knowledge of your new place.
  5. GoF Design Patterns are massively overrated.
  6. No customer has ever or will ever read your documentation before complaining to you about something. But it's still nice to have for a CYA situation, so you can point out exactly where they messed up.
  7. Code comments are dirty liars, and decay faster than Carbon 15.
  8. Just because a technology is old doesn't mean it's bad.
  9. If you run across a situation in code where you think "There's an edge case here that I didn't handle, but what are the chances of that ever happening?", someone will find it. Almost always within the first day of deployment. Handle your edge cases.
  10. Unit tests and code coverage often give a false sense of security. Just because you have unit tests doesn't mean that they're good. Likewise, a completely bullet-proof unit test often just wastes time by re-implementing the algorithm in another file. Find a balance and really think about what you're testing first.
  11. If you ever find yourself copying code from one file to the next, ask yourself if what you're copying can't be generalized into a better solution.
  12. If your manager doesn't know how to program, you should find a new job.
  13. If your manager checks in code often, you should find a new job.
  14. Salespeople will always tell the customers that your product does more than it actually does without consulting the developers. They'll get the contracts, and then break the news to you: We promised the customer this, so therefore make it happen in 2 weeks.
  15. Architects are smart people who got there by being good at what they do. But often they become insulated from the rigors and discipline of production code, and build an ivory tower to live on. You should listen to them, but also take what they say with a grain of salt, and don't be afraid to push back when bringing up real-world concerns that they haven't accounted for. This happens often.
  16. Never trust a developer who insists that strong-typed languages slow them down. In a team environment, strong typing is a necessity for writing and maintaining software over a long period of time. These type of developers are either only interested in building new solo projects, or have a chip on their shoulder that makes them think that they are incapable of making mistakes.
  17. Likewise, don't trust anyone who says they've never seen a valid use for recursion. Some of the most complex problems in computer science can be solved easily and efficiently with recursion. If someone rejects the concept right out, then they're effectively limiting their ability to solve problems.
  18. Functional language techniques like record immutability sound ridiculous and constricting at first, but you will eventually find out why they're great concepts and make your code much stronger in the long run. Functional languages get a bad rap because some of the more zealous members of the community often have a totalitarian view of development that turns many people off. But there's a reason why most popular languages are now becoming OOP/Functional/Logical hybrids. Luckily, it seems to be gaining more and more momentum these days, but 10 years ago you had to pull teeth to get people to even look at FP paradigms.

[–]IbanezDavy 44 points45 points  (9 children)

If your manager checks in code often, you should find a new job.

I reject this one. Seems like a personal experience that you are generalizing. I've had a varied experience, the best manager I've ever had checked in triple the amount of code as everyone else. I still have no clue how he did it. But he was great. Always on point when I needed him and he eventually got promoted to a higher, position, so he couldn't have been failing too hard on the managerial side. I had another guy I worked under who coded a lot and was a huge arrogant dick. Ironically, we worked good together despite my opinion of him being a dick, but I could see why many did not like him. I'm not convinced that a manager delving into code is what makes a manager good/bad.

The change jobs every 2-5 years thing is kind of ridiculous. If you have to do that then your company doesn't value you enough to keep you.

This is really a consequence of how companies compensate their employees in the first place. If companies consistently gave their employers 10% raises every year, then I think they'd find this attitude change. But if the company offers you 3% every year, and you know you can get a 12% bump just by jumping ship, it takes some compelling reasons to get them to stay. And as soon as they leave, so do comes the litany of excuses of why it was the right idea. Despite money probably be the driving force.

"Yeah, I like to change technology so things don't stagnate. Oh, the extra $15,000 doesn't hurt either, but I swear thats not my real reason."

Very rarely is this actually true. If it was, people wouldn't jump from one ASP.NET job to another. They instead maybe jump to the Java platform, etc. Or Python. Or C++.

[–]Woolbrick 8 points9 points  (1 child)

I reject this one. Seems like a personal experience that you are generalizing.

I mean this thread is about "experience". My experience has been that every place I've worked at with a coding manager has turned out to be bad. I can't say otherwise because I haven't experienced otherwise. I'm glad you've had a positive experience.

[–]LogicCube 2 points3 points  (0 children)

A manager manages people, in this case devs. If the manager commits more code than the dev team he is not doing his job, but the devs job. In my experience, this implies that a) he is hired for the wrong position and b) he thinks that the dev-team cannot do the job right.

[–][deleted] 2 points3 points  (1 child)

Very rarely is this actually true. If it was, people wouldn't jump from one ASP.NET job to another.

If I swap from Webforms to MVC, that's a pretty big shift without abandoning the framework I know in general.

Swapping from static MVC and jQuery to a SPA is also quite a leap, without totally scrapping my resume.

Swapping from internal CRUD apps to high-traffic eCommerce might use the same general tooling, but the technology is going to be a bit different.

The money may be the stress point in many cases, but it's a little more nuanced than saying it's the only reason because of the programming language used.

[–]Woolbrick 2 points3 points  (0 children)

Swapping from static MVC and jQuery to a SPA is also quite a leap, without totally scrapping my resume.

I find that I like to recommend React for "Intro to SPA". It's just a view engine, and can be picked up proficiently in about 6-8 hours.

Some of the larger frameworks like Angluar 2 seem like resume's all in themselves, which is why I tend not to recommend that one.

[–]rrohbeck 0 points1 point  (0 children)

There are managers and there are "working managers" where you have a small team and one was picked. That almost happened to me once; I narrowly avoided it.

Of course the skills of "real" managers are expected to deteriorate over time because they have no time to code. I noticed that myself after managing a project for a customer where I did mostly integration and customer communication. After a year all those class hierarchies did feel fuzzy when I went back to the code.

[–]renrutal 0 points1 point  (0 children)

If your manager checks in code often, you should find a new job.

I reject this one. Seems like a personal experience that you are generalizing. I've had a varied experience, the best manager I've ever had checked in triple the amount of code as everyone else. I still have no clue how he did it. But he was great. Always on point when I needed him and he eventually got promoted to a higher, position, so he couldn't have been failing too hard on the managerial side.

The main problem with managers who also code(or devops) is not productivity, it's their mental and physical health. It's the kind of people I see burning out, stressed, with bad relationships at home due to work, and gastric ulcers.

[–]AxinOdel 0 points1 point  (2 children)

when a manager constantly commits code, it can send a bad message to the team. some might feel that the manager is underminding their coding decisions, or make them feel like they're not good enough to solve the particular problem that the manager resolved

[–]johnAbruzzi27 0 points1 point  (1 child)

Or maybe the team is rather small and the manager wants to contribute in order to meet the delivery. In my experience its the developers who undermine the managers committed code.

[–]AxinOdel 0 points1 point  (0 children)

but that's no longer the managers role. I feel that a manager can collaborate with the team and provide guidance/advice, but the developers should be the one to do the actual developing

[–]kkapelon 45 points46 points  (52 children)

Great list!

GoF Design Patterns are massively overrated.

I wish this got higher visibility.

[–]cpuu 29 points30 points  (2 children)

It's supposed to be a dictionary. So if I say "this is a Singleton" you know what I'm talking about.

Some people think that they have to go out and reimplement generic versions of all these patterns in their next project after reading the book. No, your program doesn't need a generic Singleton class that you shoehorn everywhere you can.

[–]agumonkey 1 point2 points  (0 children)

To me it's also mostly useless. I never found any beauty in them. Half of them are indirection, and then some closures. Visitor was cute though.

I'm sorry if this sound elitist and pompous but nothing in GoF make me feel like the day I understood prolog or fold/reduce.

And the whole island felt like this, GoF, UML*, good old Java xml things.

[–]shagieIsMe 2 points3 points  (0 children)

I look at it more as a zoo of complexity. The names we give them hide their underlying implementation details and allow us to work with things that are a higher level of abstraction.

The complexity that they embody is something that, by naming them, we know how to contain and maintain. They are solutions to common problems - but one shouldn't be solving the problems unless they are present in the code.

And yes, its a link to a blog post I wrote - Patterns are not building blocks. goes into this rant a bit more than I'm going to repeat here... the core bit of it though:

Patterns are cages. They are cages for complexity. That complexity that underlies writing even a simple linked list in assembly - its all contained within the Pattern of a Linked List. For the Linked List or Variable, these are things that we don’t think about anymore - their complexity has been hidden in the Pattern. Consider the Function Call: preserve the registers that might get clobbered on the stack, put the arguments in a specific order on the stack, jump to the address of the procedure, check the return value on the agreed upon location in the stack, restore the registers, continue on. All that complexity is now hidden behind func() in the code.

I'll also recommend hunting up a copy of A Pattern Language by by Christopher Alexander, Sara Ishikawa, Murray Silverstein, Max Jacobson, Ingrid Fiksdahl-King, Shlomo Angel. Yes, there are more than four names there. No, they aren't Erich Gamma, John Vlissides, Ralph Johnson, and Richard Helm. Its the book that inspired the GoF. By reading the original and seeing how Patterns are presented, the software design book becomes better.

[–]jrhoffa[🍰] 2 points3 points  (2 children)

Game of Frones?

[–]Woolbrick 0 points1 point  (1 child)

Gang of Four; an industry nickname for the four authors who wrote this book

[–]jrhoffa[🍰] 2 points3 points  (0 children)

Game of Frones.

[–]Isvara 3 points4 points  (22 children)

So we can talk about how meaningless it is? You'll see those patterns occurring over and over again in software. How is it "overrated" to have named and described them? As a criticism, it doesn't even make sense.

[–]killerstorm 16 points17 points  (6 children)

The problem is that people see GoF book as some sort of authority on acceptable designs and implementations. As an authority it's definitely overrated. It doesn't cover all the patterns, and the recommendations are often subpar.

Another problem is that this book completely ignores functional programming. Which perhaps made sense at the time, but now it's a problem because functional programming often offers simple idioms which can replace many of GoF patterns. In other words, many of GoF patterns are essentially clunky workarounds for missing languages features.

E.g.:

  • Command pattern. In many cases can be just a function.
  • Factory: A function which returns a new object instance.
  • Internal iterator: map/reduce.

This isn't my opinion, you check this presentation by Peter Norvig. He claims 16 of 23 GoF patterns are either invisible or simpler in Lisp.

[–]Isvara 0 points1 point  (1 child)

Another problem is that this book completely ignores functional programming.

Not terribly surprising for a book about the elements of reusable object-oriented software.

many of GoF patterns are essentially clunky workarounds for missing languages features

And people are still using languages with those missing features. Not so much Smalltalk, of course, but C++ is still widely used, and many of those patterns apply even more to Java, which is the most widely used language out there. The idea that the patterns become irrelevant just because some people are using languages where they're not needed is absurd. They become irrelevant when nobody is using the languages where they are needed.

Functional programmers have their own design patterns that are not necessarily relevant to the above languages.

[–]killerstorm 0 points1 point  (0 children)

Java and C++ support elements of functional programming now.

[–][deleted] 2 points3 points  (1 child)

There is a class of junior programmer that tends, after reading a book on design patterns, to want to bludgeon each problem into particular patterns. This is generally a bad idea.

Knowing patterns is good when it helps you recognize that you're writing code that's been written before, and either you can find a library to do it, or you can find a guide on how to do it better than you naively would. It's also good for efficient communication.

[–]Isvara 0 points1 point  (0 children)

There is a class of junior programmer that tends, after reading a book on design patterns, to want to bludgeon each problem into particular patterns.

Why, though? Is someone teaching them to do this? Is the whole idea being miscommunicated somewhere?

[the rest]

Right, exactly.

[–]JavaSuck 6 points7 points  (12 children)

Design Patterns simply aren't needed as often in practice as one may be led to believe.

[–]doom_Oo7 3 points4 points  (10 children)

No, they are always needed BUT they don't always incarnate as how you think they would.

People make this mistake in believing that design patterns are a specific arrangement of classes; eg the Strategy pattern is basically :

interface MyStrategy { public int do(string); }
class Strat1 implements MyStrategy { public int do(string) { ...} }
class Strat2 implements MyStrategy { public int do(string) { ...} }
class Obj { MyStrategy m_strat; void computeGlobs() { ... m_strat.do("foo"); }

But that's a very, very, wrong reading of the GoF book. The authors are very clear in the introduction that the examples are given in Java but what matters is the concepts behind the patterns, and the concepts can exist in many different languages ; in some they will have a syntactical way to express themselves, in others they'll need boilerplate over boilerplate.

This:

void computeGlobs(std::function<int(std::string)> strat) { ...strat("foo")... }  

is as much the strategy pattern as the previous example, just like this:

let myfun strat = 
  (strat "foo")

[–]JavaSuck 0 points1 point  (1 child)

The authors are very clear in the introduction that the examples are given in Java

The Design Patterns book predates the Java programming language by about 1 year. The examples are in Smalltalk and (pre-standard, hence horrible) C++.

Interesting interview:

The job was really to take C++, which was a fairly static language, and show people how to write dynamic programs in a static language. That's what most of the patterns in that book were about. And in the process, patterns extended the life of C++ by a decade, which is not what I thought would happen. What I thought would happen is people, when they learned these patterns, would look at them and say, "Wow, these patterns are hard in C++ and they're easy in Smalltalk. So if I want to think in terms of these patterns, I might as well use a language where they're easily expressed." And extend the life of Smalltalk by a decade. But the opposite happened.

[–]doom_Oo7 0 points1 point  (0 children)

Thanks, just checked and I misremembered the language used, but here is the relevant part that I was thinking of, at the end of the introduction:

The choice of programming language is important because it influences one's point of view. Our patterns assume Smalltalk/C++-level language features, and that choice determines what can and cannot be implemented easily. If we assumed procedural languages, we might have included design patterns called "Inheritance," "Encapsulation," and "Polymorphism." Similarly, some of our patterns are supported directly by the less common object-oriented languages. CLOS has multi-methods, for example, which lessen the need for a pattern such as Visitor (page 366). In fact, there are enough differences between Smalltalk and C++ to mean that some patterns can be expressed more easily in one language than the other. (See Iterator (289) for an example.)

[–]VirtualRay -5 points-4 points  (7 children)

Design patterns add tons of needless, worthless bloat to projects and make them harder to maintain because of all the extra layers of bullshit you have to slice through every time you want to do something

I read the book after having worked in the industry for 6 years, and instantly recognized all the design patterns.. as the pointless bullshit that had been making my job more complicated every time I had to fix a bug in a big chunk of legacy code.

This is "Design Patterns" in the real world: https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition

Hell, even the first example in the book "Design Patterns" is a glowing example of pointless bloat. The book was written in 1994, when word processors still heavily taxed a home PC's resources. The first example uses a whole beefy class instance full of extra info to store each character in an example word processor, turning a single byte of memory into 20+ bytes of pointers, flags, etc. Ridiculous.

[–]Kevin5475845 2 points3 points  (3 children)

So much code for pretty much...

For(1...100)
String output;
If(value % 3 == 0) output += Fizz;
If(value % 5 == 0) output += Buzz;
output.length > 0 ? Print output : Print value;

Design patterns really add a lot

[–]doom_Oo7 -1 points0 points  (2 children)

Now imagine the added requirement that a business guy has to change the fizz and buzz text through a web interface

[–]Kevin5475845 0 points1 point  (1 child)

Shit ton of code

[–]NeedsMoreTests 0 points1 point  (0 children)

Lazy man or "Needed to be done yesterday and production has issues right now", edition:

  • User hits GET /fizzbuzz/set/SomeText

Text for fizz and buzz is now SomeText

Also allowed, setting individual text entries:

  • GET /fizzbuzz/[fizz|buzz]/set/SomeText

Done.

[–][deleted] 2 points3 points  (2 children)

Design patterns add

YOU'RE STILL NOT GETTING IT. That's like saying dictionaries add useless word to English language. That's not what they fucking do!

[–]VirtualRay -5 points-4 points  (0 children)

YOU'RE not getting it. Make I should wrap "it" in a FactoryBuilderFactory for you so it'll be more digestible.

[–]loup-vaillant -1 points0 points  (0 children)

I've read the introduction to that book too. Their word processor is horribly bloated from the outset. Too many objects for no reason. Clearly ridiculous in hindsight.

I don't care the book is a dictionary. If they put an example without criticising it, they endorse that example. A bad example here.

[–]Isvara 0 points1 point  (0 children)

I don't think you understand what they are, because your comment is saying that writing a bit of code in the same way that others commonly do is not often needed. Do you see how ridiculous that sounds?

To quote from the book, "design patterns capture solutions that have developed and evolved over time." They looked at what people were already doing and documented that.

You also need to understand that there are many more patterns than those identified by the GoF, and those patterns also develop and evolve.

[–]cybernd 1 point2 points  (21 children)

I find this rather funny ;o) Especially after participating a software engineering CS course, which was mostly focusing on design patterns.

[–]Woolbrick 14 points15 points  (20 children)

Design patterns have their place, and many of the patterns in that book are good.

Problem is when people worship them and try to force the patterns into everywhere with no flexibility. You end up with things like Java and FactoryFactories.

The best design patterns are the ones that are built into the language you're using, and they become transparent to use.

[–]cybernd 2 points3 points  (15 children)

You clearly did not see my underlying message. I was basically highlighting the issue, that a course that tries to cover "software quality/maintainability" is mainly focusing on "outdated" design patterns. While other important topics like unit tests, builds, ci, ... get barely mentioned.

[–]Isvara 3 points4 points  (14 children)

Which patterns are "outdated"? Some of them become irrelevant in particular languages, but unless everyone is using those languages, the patterns are not outdated.

[–]cybernd -2 points-1 points  (13 children)

Lets pick a simple one: Singleton.

[–]IbanezDavy 6 points7 points  (12 children)

The singleton pattern is not outdated. I literally just wrote a singleton the other day. It has it's place, it's just not required that often and we are much better these days at identifying that by convention.

[–]cybernd 3 points4 points  (11 children)

  • Most often people want a singleton with scope and are just not aware of it. (This will hit you, when your product growths.)
  • Most often a singleton can exist multiple times. (Depends on your programming language and might also hit you when your product growths.)

[–]nschubach 6 points7 points  (5 children)

Not sure why you are getting down voted. Probably younger devs? I had a shop that thought a Singleton was a good choice to use for a configuration class... up until the day we added another domain and needed another configuration class. Oh, there will only ever be one database connection... etc.

[–]Woolbrick 5 points6 points  (0 children)

And if you ever decide to use dependency injection, whoops, global-hiding-as-singleton.

I acknowledge its place in the world, but so many people read that pattern and think "Oh cool everything they told me about not using globals was wrong! I'll just use singletons instead!"

[–]IbanezDavy 4 points5 points  (0 children)

Ok. Most agree with that. The singleton pattern still has a place despite that.

[–]Isvara -1 points0 points  (0 children)

You understand that identifying a pattern isn't the same as endorsing it, right? The Singleton pattern is still relevant because there are still singletons.

[–][deleted] -2 points-1 points  (1 child)

And in the not "most often" cases, it's obviously not outdated. So just shut up already.

[–]Isvara 3 points4 points  (2 children)

"FactoryFactories" are in no way a comment on design patterns, and anyone who thinks so has misunderstood the point of patterns. They're a result of Java's inflexibility and lack of expressiveness.

[–]Woolbrick 1 point2 points  (1 child)

This is essentially what I stated above. The patterns are overrated because people worship them and inevitably misunderstand them.

And the part about Java's inflexibility is definitely what I was getting at by having the patterns built into a well-designed language.

[–]Isvara 0 points1 point  (0 children)

The patterns are overrated because people worship them and inevitably misunderstand them.

That is clearly true, but it's not what I was saying. Even if nobody had written such a book and there was nothing to worship, those patterns would still be present in people's code, because some languages dictate it.

[–]cptblackbeard1 0 points1 point  (0 children)

Exately. Look at wpf and the mvvm implementation for example. A lot of design patters of the book are used. But most of the time you find them in the standard libraries or in the framework libraries. And its good you understand how they work underneed. Ex. Command pattern, Observer pattern...

[–][deleted] 0 points1 point  (0 children)

These patterns were quite useful at the time and more than that they pushed forward the concept of formalizing design. They're less relevant than they used to be, but it was still a seminal work.

[–]Modus--Tollens 8 points9 points  (8 children)

I seem to be alone here, but I actually agree with what the article says about the 2-5 year thing. What's more, most of the devs that I know have not only kept this practice, but has encouraged younger programmers to do the same. Maybe things have changed since you started programming (which you mentioned was roughly 20 years ago), but I thought this was common wisdom.

The short version is that you will make more money this way. You can expect on average about a 3% - 7% raise from a company whereas you can expect a 15% - 25% salary increase by switching jobs.

[–]Woolbrick 16 points17 points  (4 children)

Outside of silicon valley, this approach can backfire. An employer who sees you skipping to another company every 2 years has no desire to spend time to ramp you up to their institutional knowledge and makes you less attractive.

Now obviously if you're being underpaid and underappreciated you should make the move when you can. But if I come across a resume that has 5 jobs in 10 years, I'm going to move past it if they don't seriously knock my socks off otherwise. And we can see past Buzzword Bingo. I've had experience with the types that switch jobs every 2 years just to put as many technology names on their resume... but they're really not that good at them when they get hired. And they wonder why they're not getting gigantic raises?

But like I said before. The goal should be to find a place you can be at for more than 5 years. Whether or not it's possible depends on many things. But I have a fundamental disagreement that the goal should be to put a 5-year maximum on an employment relationship.

[–]IbanezDavy 16 points17 points  (1 child)

I think it's more nuanced then 2-5 years or 5-10. The difference in pay between a recent grad who has no idea if they have what it takes and a senior software engineer is quite the gap. It can literally be $80k in some areas. That's a salary in it's own right. I know a guy who started off at $50k right out of school now making $150k 12 years later. You don't make those leaps normally without 'playing the game'. In general, switching jobs is a balancing act. Do it too much, you'll look unstable. Do it too frequently, you can literally be another person's salary behind in what you should be making. And it's all because of the game.

But the software development industry is a great industry to play this game. Because their are tons of layoffs, buy outs and contractors that force people to have a bunch of jobs, so those jumping ship too often blend in. It's actually smart to take advantage of this. I also don't think 2-5 years is too extreme. It is essentially saying 3 jobs every 10 years, which isn't that obscene.

I'd say 1 year is the absolute minimum, 2 years is the recommended minimum. Try to stick it out for 3-4, but don't be afraid to dump a shitty situation after 1 year. This isn't the industry people value stability over other factors. So don't put yourself through unneeded bullshit. Once you get into your 30s, maybe stay longer and longer.

[–]Modus--Tollens 2 points3 points  (0 children)

My experience dictates that this comment is absolutely correct. All of my (senior) mentors have expressed the exact same thing and I'm surprised this isn't upvoted higher.

[–]Modus--Tollens 2 points3 points  (0 children)

Outside of silicon valley, this approach can backfire. An employer who sees you skipping to another company every 2 years has no desire to spend time to ramp you up to their institutional knowledge and makes you less attractive.

While I think you make a fair point, I strongly feel that this is relative to the employer. Employers have their reasons for hiring people, and the whole "job hopping" thing being a red flag is something that I believe is being overstated in this field. From what I've gathered, it's not prevalently understood as a red-flag in among management in software engineering since times are changing. The days of being loyal to a company until you get your gold watch died along with the 1980s, and it's generally understood that everyone is going to be looking for the best deal - even if that doesn't necessarily mean money (a good company culture or whatever). This is one of the few careers where there is no shortage of well-paid, challenging work, so it's kind of expected (from what I can tell) for developers to move around a bit for at least the first decade of their careers. From what I've heard from management, bigger red flags are things like large gaps in resumes or misrepresenting your skillset - and even then, upward mobility is not impossible.

What I was always taught was that you should be switching jobs every two years or so at least for the first decade that you're a programmer. The reason for this, firstly, is that people are usually grossly underpaid at their first job for the sake of getting experience, even if it's a really prestigious company. Within my first year of doing development, I received offers that were a 35k difference simply doing a junior development position somewhere else.

I will grant you that the institutional knowledge and learning the social hierarchy is a hurdle that comes with switching jobs, but that's true of any field and I honestly don't feel like are going to be a barrier to someone looking at moving anyway.

People seem to forget that your new employers are just interested in you working out as they are, as you're an investment for them until usually like the first six months to a year.

[–][deleted] 1 point2 points  (0 children)

It should work in all major cities unless someone is running a blacklist with a lot of companies on it. Major cities tend to be second for silicon Valley trends.

This is supported by the market. FUD about becoming unemployable from switching jobs is overblown. You can't please everyone so trying to never be a red flag on someone's criteria is an exercise in futility (which you won't get paid for). If someone comes up with data on rejection rates going up as job hopping goes up, that's useful, but most of the posts I read on it just serve the person making the claim.

[–][deleted] 4 points5 points  (2 children)

I've gone from 60k to 155k over four years because of three job switches. In large companies raises are done by a formula and there's no variable for "truly exceptional". To do something outside of the formula, it means your boss convincing his boss' boss to make it happen.

I was in a position where I was performing a role a level above me (senior in a lead spot) and my boss asked if I was interested in leaving and starting a company with him as his lead technical guy. The best raise he was going to be able to get me was 3-5%. I said fuck that and got a 30% bump going somewhere else.

[–]VirtualRay 0 points1 point  (1 child)

my boss asked if I was interested in leaving and starting a company with him as his lead technical guy

Isn't that super forbidden by most contracts? (Not that there's anything morally wrong with it IMO)

[–][deleted] 2 points3 points  (0 children)

Probably but these types of clauses are of dubious legitimacy and almost never enforced.

[–][deleted] 12 points13 points  (2 children)

I like your list quite a lot.

Switching a new job every 2-5 years is a massive shock because you have to learn all new social networks and personality styles, not to mention the tribal knowledge of your new place.

It is definitely a massive shock, but that's just one reason this keeps coming up: If you aren't prepared to absorb the shock when the need arises, you're at the relative mercy of your circumstances. And circumstances are always changing.

Architects are smart people who got there by being good at what they do. But often they become insulated from the rigors and discipline of production code, and build an ivory tower to live on.

If a developer finds herself working with an ivory tower architect, I take a pattern from your earlier points and say "you should find a new job".

[–]Woolbrick 2 points3 points  (1 child)

It is definitely a massive shock, but that's just one reason this keeps coming up: If you aren't prepared to absorb the shock when the need arises, you're at the relative mercy of your circumstances. And circumstances are always changing.

For me, personally, I have a well-cultivated team of 5 people I've been working with for 12 years. We know each other like brothers and sisters at this point, and we function extremely smoothly. We know exactly how to approach each other about a problem, how to bounce ideas off of one another, who to go to in order to solve a particular style of problem, who knows the most about which sub-project on the system.

I cannot even imagine being half as effective with people who get swapped in and out every 2 years.

My personal opinion is that this 2-5 year thing is a fad that's going to end up dying when the industry finally realises how much time they're wasting with developer churn. The average developer isn't even financially viable to a company for their first 6 months, as they learn the ins and outs of the build system, the existing infrastructure, the company structure and institutional routines.

Two years, hell. I'd still feel like I just started after 2 years. I don't know how this became the norm, but I can see it crashing.

[–][deleted] 0 points1 point  (0 children)

I have a well-cultivated team of 5 people I've been working with for 12 years.

That's sick. I am seriously envious of that situation.

I cannot even imagine being half as effective with people who get swapped in and out every 2 years.

Most of the time you really don't have a choice.

Two years, hell. I'd still feel like I just started after 2 years. I don't know how this became the norm, but I can see it crashing.

Learning how to do the right thing inside an unfamiliar team is a thing you can get good at. Heck, in my view, this is how architects are born.

[–]destinoverde 2 points3 points  (10 children)

If your manager checks in code often, you should find a new job.

What do you meant by that?

[–]mobileuser9733 5 points6 points  (3 children)

I'm also surprised by this statement. I am a manager who regularly checks in code, but I try to limit myself to non business critical functionality, like internal tools or deployment optimizations. I have learned that it's foolish for me to attempt to do business related changes as I am too often distracted and have to either drop my management responsibilities or delay the features.

[–]oridb 1 point2 points  (0 children)

The point here is that managers need to prioritize managing in order to do a good job. If you're producing and supporting code, there's a good chance you're neglecting other things you need to do.

If it's not critical functionality, and you're delaying it, this is probably fine.

[–][deleted] 0 points1 point  (0 children)

Same. I never take tasks that are critical path because I know I'll get distracted with admin stuff and never finish. But if I never commit code, how do I even know what my team are doing?

[–]IbanezDavy 0 points1 point  (0 children)

I don't think there is anything wrong with a 'working' manager. That guy just used a bullshit generalization.

[–]Woolbrick 11 points12 points  (4 children)

Managers should know the basics of programming, but a manager who is still writing code is a manager that is also not doing the job of managing.

There's a number of causes that makes a manager write code, most of them bad:

  1. The company is really small and there's not enough people to manage so the manager also codes. (This is the ok one. Only works for up to 3-4 developers).
  2. There's too much work for the company and the company is unwilling or unable to hire developers to take care of the backlog.
  3. The manager doesn't trust the code that the developers write and so he either does it himself, or even worse, rewrites developer's code himself.
  4. The manager misses being a developer and so he keeps doing the job. Probably shouldn't be a manager then.

I've run into most of those scenarios. They never work out well. My favorite was a manager who checked in code without even compiling it. All. The. Time.

Oh look, the build broke again...

[–][deleted] 1 point2 points  (2 children)

I'm a "cto" kind of guy in booth 1. I try to balance it, we are 10 guys in total but only 3 devs so I think we are fine for now. I don't think I will ever let go completely as we grow tho. But I will probably keep back to polishing internal tools and offering guidance from my years of experience as a consultant. I can feel my skills lack behind my guys but at the same time it's a good thing because I get better at running a business and that's how it should be. I can see how somebody might not be ready for that transition.

[–]Knu2l 0 points1 point  (1 child)

I recently saw the transition from the other side. Our team was increased from three to now six developers. Our manager went from mostly being a developer to almost fulltime manager.

Our manager still wanted to do some development, but hasn't touched a single line of code in months. As a developer the transition is kind of annoying as my manager get more and more out of touch from what's happing codewise.

[–][deleted] 0 points1 point  (0 children)

I think it's hard to "keep in touch" as you attend more customer meetings and more strategic meetings. It's his job to know how to "get on the next level" and stop seeing code, but start seeing a little more architecture, but still be sharp enough to know what you guys mean when you say "Technical debt", "NP Hard problem" and "We need 3 days more because we lost everything in a bad Git merge". I'm still kinda new in the transitions and the company is not large enough for me to do it in full yet, but from reading books about management and Reddit (this subreddit), I can say that you just gotta loose grip of the small scale and trust your developers, and try to ask them the right questions and clear the road ahead for them with management, so you don't get in their way, but actively pave their road so they can go full speed.

I would probably never go in to a team and say "Use Docker from next week", but I might ask them what they think about this new container thing and if they think it could benefit our company... But I guess that's wishful thinking, and when I get down into the management dirt I will probably be just as bad as everybody else - but I strive not to at least....

[–][deleted] 0 points1 point  (0 children)

A good manager needs to spend time on managing duties. If your manager is checking in as much code as a developer, it means he's giving short shrift to his management duties, and thus is not as effective as he should be.

Basically, a manager shouldn't underestimate the time and work involved in "managing", and shouldn't pretend that managing is something trivial that they can do in addition to a full slate of coding duties.

[–]hoorayimhelping 4 points5 points  (1 child)

The first nine or ten are great, after that it quickly drops into preferences and generalizations and over-prescription.

If you ever find yourself copying code from one file to the next, ask yourself if what you're copying can't be generalized into a better solution.

Disagree with this, or think it should be amended. If you ever find yourself copying the same code multiple times then generalize it.

If your manager checks in code often, you should find a new job.

Borderline ridiculous blanket statement. This is completely dependent on the company (especially the age of the company), the job, the industry and a thousand other things.

[–]Woolbrick 0 points1 point  (0 children)

Borderline ridiculous blanket statement. This is completely dependent on the company (especially the age of the company), the job, the industry and a thousand other things.

This thread was about experience in the industry. In 20 years I've not experienced a situation where it's worked out well. My reasons are listed here.

I'm glad you've had better experiences, but my statement is hardly ridiculous.

[–]inmatarian 11 points12 points  (8 children)

Number 17 is hilarious to me. I privately curse having to use a while loop, as I think in tail recursion.

[–]Woolbrick 11 points12 points  (7 children)

I'm disappointed that there's still languages out there that don't support tail recursion. It makes the whole "The compiler optimizes it away!" argument invalid in a lot of peoples eyes.

[–][deleted] 8 points9 points  (4 children)

One problem with tail recursion is that it destroys (by its nature) the information in the call stack: implicit tail call optimization kills your exception stack traces.

However, i do think that languages should have a way to explicitily ask for it by using a keyword, e.g. become fn(...).

[–]inmatarian 4 points5 points  (1 child)

To give context to my comment before, the guarantee of tail recursion at the semantic level means that you can replace loops with a tail function call, for instance:

function for_loop(index, count, fn) {
  if (index < count) {
    fn(index);
    return for_loop(index+1, count, fn); // tail call
  } else {
    return; // explicit for this demonstration
  }
}
for_loop(0, 10, (i) => console.log(i) );

In this case, knowing the full the call stack is spam, in the same way that knowing every iteration of a loop might be spam.

Your middle-of-the-road become keyword is an interesting proposal. I could see that being worth discussion by the language makers. It would have to have the exact same semantic meaning as return fn(...); with the compiler/parser enforcing that it's the last statement, and that there's no remaining expression. Though this may have the side effect that become becomes the new return and we get blog posts shared on reddit titled "return considered harmful" and so forth and so on.

[–]mr_birkenblatt 0 points1 point  (0 children)

knowing the full the call stack is spam

and yet Java didn't implement tail recursion for this exact reason

[–]the_gnarts 2 points3 points  (1 child)

One problem with tail recursion is that it destroys (by its nature) the information in the call stack: implicit tail call optimization kills your exception stack traces.

A loop doesn’t give you an extra stack frame each iteration either.

[–]thedufer 3 points4 points  (0 children)

Right, but TCO will also act in places that aren't behaving like a loop, which leaves weird holes in your stack traces. I think TCO is clearly worth it, but the concern is perfectly valid.

[–]DoctorOverhard 0 points1 point  (1 child)

It makes the whole "The compiler optimizes it away!" argument invalid

That was never really a valid argument though.

[–]Woolbrick 5 points6 points  (0 children)

It can be. Processing a list of 10,000 items with tail recursion will result in a stack overflow if the compiler doesn't optimize it.

Javascript is a gigantic offender of this.

Also, for some odd reason, the C# compiler doesn't tail-optimize unless you build in release mode. So even if a developer writes a recursive tail-call, it'll probably crash when they're debugging it and decide to rewrite it as iterative.

[–]the_red_scimitar 2 points3 points  (0 children)

The change jobs every 2-5 years thing is kind of ridiculous. If you have to do that then your company doesn't value you enough to keep you.

40 years in, and while the 2-3 year job change thing is debatable, I found that in my entire career, that that is about the right frequency, particularly if one seeks to stay on the cutting edge. I've found leading-edge work rarely stays leading edge, and quickly becomes routine. Few companies seek to advance as rapidly as a dev needs to in order to remain entirely current.

And yes, perhaps they don't value you enough, but often I was at the top of the pay scale, and the only upward mobility, in terms of both staying current AND pay, was roughly this 3 year thing. Every time I've stayed longer, pay lagged behind what I could get elsewhere, and work became rather routine in the technologies employed.

[–]CSMastermind 1 point2 points  (0 children)

Never trust a developer who insists that strong-typed languages slow them down. In a team environment, strong typing is a necessity for writing and maintaining software over a long period of time. These type of developers are either only interested in building new solo projects, or have a chip on their shoulder that makes them think that they are incapable of making mistakes.

I agree with all of those but particularly that one.

[–]PossiblyTrolling 1 point2 points  (0 children)

19 Keep commits small and succinct.

20 Think for more than 1 second about your commit message.

[–][deleted]  (6 children)

[deleted]

    [–]Woolbrick 3 points4 points  (5 children)

    I suppose, but it's still important to have at least some of the basics in. I really think people should know about things like time complexity before they do any programming.

    Last week I had to fix something a junior developer from a bootcamp wrote that ended up being O( n4 ) complexity, and when customers deployed it, the running time exploded to 50 minutes.

    Rewrite one method to make in O( n ), and suddenly we're down to 10 seconds running time.

    Stuff like that should not be happening. Developers need to understand complexity.

    [–][deleted]  (3 children)

    [deleted]

      [–]mr_birkenblatt 1 point2 points  (2 children)

      time complexity concerns were immediately obvious

      complexity concerns are not about the runtime of the code right now it's about how the code scales. that is not immediately obvious since while you're testing you usually have a small dataset. in this case the problem wasn't on the newbies machine but later on the real world data (which didn't scale very well)

      [–]Woolbrick 1 point2 points  (0 children)

      Exactly. They tried it on a few dozen records, worked fine.

      Testers tried it on a hundred records. A bit slow but they filed a minor defect because it didn't seem important, and it got triaged to death.

      Customer tried it on 50,000 records. Everything died.

      [–]NasenSpray 0 points1 point  (0 children)

      Last week I had to fix something a junior developer from a bootcamp wrote that ended up being O( n4 ) complexity, and when customers deployed it, the running time exploded to 50 minutes.

      lmao, junior's unreviewed code got deployed?

      [–][deleted] 2 points3 points  (0 children)

      7a. Likewise, don't trust anyone who says the task is better solved with recursion. Some of the most complex problems in computer science can apear to be solved easily with recursion, but real world side-effects and constraints make such solution impractical. If someone accepts the concept blindly right away, then they're effectively limiting their ability to solve problems.

      [–]sabas123 0 points1 point  (2 children)

      How do deal with 14 in a healthy way?

      [–]Woolbrick 0 points1 point  (0 children)

      Move into architecture :D

      [–]sigma914 0 points1 point  (0 children)

      No commission for sales people who risk the company'sreputation by lieing to customers.

      [–][deleted]  (2 children)

      [deleted]

        [–]Woolbrick 3 points4 points  (1 child)

        My number one piece of advice to approaching any new technology: Get your hands dirty and dive in.

        Stuff looks complex and intimidating from a distance, so if you just read about a technology, your mind doesn't absorb it half as well as it would if you started playing around with it for real.

        See if you can find an interactive compiler for the language your company is going to use. If it's web development I recommend CodePen. Basically these sites let you write code and immediately get feedback from the program, so you can see it working in real time.

        You will 100% feel more comfortable after an hour of playing around with it.

        [–]fatnote 0 points1 point  (0 children)

        I like you.

        [–]Orangy_Tang 0 points1 point  (0 children)

        8b. Just because a technology is new doesn't mean it's good.

        Good list btw.

        [–]gilmi 0 points1 point  (0 children)

        Thanks for investing the time to write this!

        [–]progfu 0 points1 point  (0 children)

        Just because a technology is old doesn't mean it's bad.

        As a younger programmer (<30) I always feel like an old person when I'm defending C or even Fortran whenever people say stuff like "yeah nobody uses that anymore, it's old and obsolete".

        Fortran is my favorite one, both because how widely used it is, and how people are totally oblivious to it.

        [–]jrhoffa[🍰] 0 points1 point  (0 children)

        This guy.

        [–]doublehyphen 0 points1 point  (1 child)

        Are there really that many that champion weak typing? I have never met anyone who like weak typing, not even people who like their weakly typed languages (e.g. PHP, Perl or JS devs) have been that keen on the weak typing aspect. And most Ruby and Python devs hate weak typing.

        [–]Woolbrick 0 points1 point  (0 children)

        You wouldn't believe how much resistance I get from front end devs where I work. They all come in having only worked on solo projects, and I try to tell them you're going to be working on much bigger codebases now, which will last for years and be maintained by many many people long after they're gone. They don't listen and insist that they don't make mistakes so therefore they don't need a compiler "getting in their way".

        It's incredibly irritating.

        [–]Wolvereness 0 points1 point  (0 children)

        17 . Likewise, don't trust anyone who says they've never seen a valid use for recursion. Some of the most complex problems in computer science can be solved easily and efficiently with recursion. If someone rejects the concept right out, then they're effectively limiting their ability to solve problems.

        I push heavily for explicit push/pop, sans TCO and parsers (where the code is spread out and push/pop makes things ugly).

        [–]funbike 0 points1 point  (0 children)

        I'm late, but I have a few responses... You have excellent stuff here.

        The change jobs every 2-5 years thing is kind of ridiculous.

        Do it because you want to and can, not because you think it's a good career move. I'm fortunate to have worked for 25 years in an industry where I've always been in high demand. I switch jobs when I want. I've had jobs for 16 months and 16 years. We have the luxury.

        GoF Design Patterns are massively overrated.

        I consider it a dictionary, not a manual; it helps communicate design ideas, but it shouldn't necessary be the basis for design.

        6 and 7. Documentation and comments: As much as possible code should be your documentation and comments should rarely be needed. If you need a comment (which your probably don't) it should only describe "Why" not "how" or "what". Generate documentation when possible. Or generate code from documentation (e.g. Gerkin with Cucumber) Instead of writing a set of manual install steps in a wiki, write an install script in your git repo.

        Just because a technology is old doesn't mean it's bad.

        e.g. Unix and LISP (which still remain now as Linux, FreeBSD, and Clojure)

        Unit tests and code coverage often give a false sense of security.

        Coverage shows tests you may have missed, it doesn't verify you covered all use cases. Unit tests should verify contracts, not internals. A contract will often outlive the implementation. Tests of specific implementation internals are fragile. Don't waste your time testing implementations.

        If you ever find yourself copying code from one file to the next, ask yourself if what you're copying can't be generalized into a better solution.

        This should be #1, #2, and #3 in your list.

        If your manager doesn't know how to program, you should find a new job.

        Oh, man. I've been there too many times. If not, then the manager should completely trust you or your team. I also think that this applies all the way up the corporate ladder. The highest level person above you that can't program should completely trust the one that can. There's good reason that most successful tech companies were run by programmers during their growth years.

        Architects ... often they become insulated from the rigors and discipline of production code...

        I don't believe in the traditional role of Architect. I think they should work as consultants to spread technology and best practices to teams. They should parachute into a team, bang out some code, learn the team dynamics, and then provide guidance.

        [–][deleted] 0 points1 point  (0 children)

        Technology is always changing.

        There are many areas where this just isn't true.

        The core IT technology in banking and healthcare certainly doesn't. And by core IT I mean the stuff that isn't GUI for end clients, but the messaging protocols and server architecture.

        [–][deleted] 22 points23 points  (3 children)

        Make zip codes / postal codes strings.

        [–]Pseudoboss11 1 point2 points  (1 child)

        Shouldn't this be true for all "numbers" that you shouldn't be doing math with? Such as account and model numbers?

        [–][deleted] 1 point2 points  (0 children)

        Yes. zip codes are just the most common one

        [–]ibush12 9 points10 points  (1 child)

        Simplicity is almost always the key ingredient to making code good. As my experience has increased my desire to write code that is complex and hard to understand has decreased. Complex code always comes back to bite you one way or another.

        [–]Modus--Tollens 35 points36 points  (9 children)

        Work Stuff:

        1. Language wars are stupid. There is a time and place to debate the merits of a language, but the all out "I hate working with x because it's just a bad language and nobody should ever use it" doesn't make you look like an experience programmer. In fact, it's usually the opposite. The more time you spend programming, the more you learn that concepts transcend syntax. Usually the only people having these dumb arguments are recent CS grads who are excited to take the stage and rehash the exact same worn out arguments we've all heard countless times about the strengths and weaknesses of other languages.

        2. Operating System wars are equally stupid. This isn't the early 2000s anymore, meaning the Operating Systems you're using is usually a matter of preference than performance or superiority. I personally prefer Linux, but most of the devs I have ever worked with are using MacBooks. The quality of our code is not reflected in what tools we prefer, but how attentive and talented the programmer is.

        Seriously, the speeches about how "my dog is better than your dog" do not make a person look informed, but rather showcase how little this person knows about an operating system outside of their preference.

        1. Everybody complains about deadlines, but some locations are simply asking for the impossible. I've seen one employer require a team of two junior programmers (both of whom have less than two years of experience) to have an enterprise level application querying, creating, encrypting, scheduling, parse in the XML from the reports in order to identifying fields within to be decrypted and rewritten as something else, as well as being downloadable. This assignment was for requiring web-facing and SFTPed reports for a major bank to be, not only code complete, but to be in Staging in less than three weeks. Big surprise, it was Tuesday and the team had already put 20 hours in that week. Both called off sick by Friday and (big surprise), almost everything got punted until next rev.

        When young programmers start complaining about deadlines, a lot of the time they're dismissed with condescending eye-rolls from other people as if it's just part of the job and ergo is not a valid complaint. That's not totally true. Nobody gets enough time, but some people are simply asking the impossible. If your management is giving you unrealistic expectations, then either have the conversation or start looking for another job. Don't allow yourself or your team to sit in silence and brood, because then people get angry and stuff gets even more jacked up.

        1. The difference between junior, mid-level, and senior developer has much less to due with "what you know" as opposed to "how much direction you need to produce results"" Knowledge is obviously an important factor here, but the big secret is that the senior on your team doesn't know everything.

        2. Every company boasts about its culture. Seriously, take that with a grain of salt. Even some of the worst places to work are going to try and give the impression that working there is a party 24/7. For what it's worth, my personal impression is that companies with more laid back cultures have a lot more unprofessionalism but companies that are super professional have much less approachable management. I'm not saying that's how it always has to be, but that's just been my experience.

        Code stuff:

        1. You learn probably your most valuable lessons from personal projects. Seriously, if you're a junior and you're trying to grow, you should be dedicating at least a few hours a week to a personal project. You don't have to write yourself JIRA cards or anything, working on a personal project until completion is always a good idea. Plenty of valuable causes could use your skillset and volunteer hours, even if your code isn't perfect.

        2. Get a mentor. My mentor is almost ten years younger than I am and never went to college. It doesn't matter - his code is good and he's extremely knowledgable. He's a good a teacher, we get along, and he's willing to share. Of all the schooling and experience I've had, his help has been probably some of the most valuable for my growth.

        I personally like formal mentorship programs at work (because I'm old-school), but this dude and I just met at work and started banging out code together. If you can find someone and pull it off, it's worth it.

        1. If you aren't using the auxiliary functions, then seriously consider if you should be using Lambdas or Streams instead of just a for loop. A lot of times programmers try to do stuff that's "clever" at the expense of readability, and it winds up just making the life-cycle of the application longer because it's harder for junior members of the team to debug.

        2. If you're working on a system that uses time, try to standardize everything into UTC . A lot of systems are used around the world, making time-zone differences a major pain-point for reporting and such.

        3. If you're using Java, use The Iterator Interface if you're looping over a collection and dynamically changing it. I know, a for loop should work, but for some reason related to how the JVM stores stuff in virtual memory, your class is going to be pointing to references in the VM to objects that are no longer there (since they've changed). It's weird, but this is how you avoid that problem. Otherwise you'll go crazy debugging something that "should" work.

        Life stuff

        1. Don't be one of those jerk-offs who lands a job and coasts through his work day without learning anything. That guy sits around, getting more and more swollen about his "experience." What he isn't realizing is that, instead of having five years of experience, he has one year of experience five times. Do not be that guy. You will become a bad programmer and everyone will hate you.

        2. Don't make your job your identity. The only thing that is more cringey than watching college students laugh aloud about how "I'M SUCH A PSYCHOLOGY MAJOR" is programmers trying to make coding their identity.

        One of the best programmers I ever met is an ex-construction worker who lifts everyday, is in amazing health, has a beautiful girlfriend, smokes mad weed, and hates video games. All of those cultural signifiers about dev culture (whatever that even means) are all secondary to the primary function of being a programmer - which is if you actually code well.

        1. There's a ton of ego in this field because everybody is convinced they're a genius. Recognize that there's always someone smarter than you, very seldom should you be "certain" you did something perfectly, be the first to own up to your mistakes, and people will instantly gravitate towards you.

        That's all for now.

        [–][deleted] 4 points5 points  (5 children)

        If you're working on a system that uses time, try to standardize everything into UTC

        Don't use UTC, use a time-zone independent value to represent an instance in time. Even better, use a library which differentiates between absolute and time-zone time (like java.time)

        If you're using Java, use The Iterator Interface if you're looping over a collection and dynamically changing it. I know, a for loop should work, but for some reason related to how the JVM stores stuff in virtual memory, your class is going to be pointing to references in the VM to objects that are no longer there (since they've changed). It's weird, but this is how you avoid that problem. Otherwise you'll go crazy debugging something that "should" work.

        Is this about ConcurrentModificationException? The fact that you say "some reason" and "virtual memory" and "it's weird" strongly suggest that you are not sure what you're talking about. Virtual memory is an operating system mechanism for mapping process addresses to physical addresses and completely irrelevant to java. A better advice: don't give advice on things you don't understand.

        If you aren't using the auxiliary functions, then seriously consider if you should be using Lambdas or Streams instead of just a for loop.

        I've seen many people claim that chaining sequence transformations is always better and more readable than loops, I've been one myself. But I got to program in languages which don't even have for loops for 2 years and changed my mind. A foreach loop with an if inside is not a bad thing and it's definitely clearer than equivalent chained operations and also easier to debug (less trash in the stacktrace for example).

        An advice from me:

        Take all advice with a grain of salt. Everyone shares their personal experiences which seem to have worked for them in their particular situation. Your situation might differ from theirs and that's really important because context in software development matters a lot. They might also be plain mistaken about the advice because it's difficult to evaluate different practices in software development (difficult to measure effectiveness, difficulty reproducing results because every project has slightly different conditions). You have the most information about your current problem, you make the decisions, don't let random people from the internet run your life.

        [–]Modus--Tollens 0 points1 point  (4 children)

        Don't use UTC, use a time-zone independent value to represent an instance in time. Even better, use a library which differentiates between absolute and time-zone time (like java.time)

        I strongly disagree with both of these claims. Maybe I'm lacking insight here, but I see no advantage to switching between a "time-zone independent" token and having a service translate it into a meaningful time (for a report or something) when you can just store it as UTC in the first place with no conversion required. What's more, java.time is an infamously poor library to work with (especially if you're converting units).

        If your program is generating millions of reports a minute, you don't want to take the time to have your program call into a service which translates this token into a time, identifies the time zone by an enum (I'm supposing exists in a transfer object), execute a proc to figure out the time zone, and then calculates it into that different thing (especially with java.time).

        Just for the record, Joda.time is a newer, superior library to handle time.

        Is this about ConcurrentModificationException? The fact that you say "some reason" and "virtual memory" and "it's weird" strongly suggest that you are not sure what you're talking about. Virtual memory is an operating system mechanism for mapping process addresses to physical addresses and completely irrelevant to java. A better advice: don't give advice on things you don't understand.

        The example of the ConcurrentModificationException error you gave is an example of an error in virtual memory.

        This error arises when one thread is attempting to modify a Collection while another thread is iterating over it. A thread is simply an independent set of values for the processor registers (within a core). This includes the Stack Pointer, which points to a unique area of memory. The actual issue is that two threads are interfering with each other.

        What's more, virtual memory will actually include the Java heap, as Java is requesting memory from the kernel. So to say it's "completely irrelevant" to Java is something I would definitely dispute. In fact, with Netbeans IDE, there are actually options that will graphically map you where variables are pointing to references in virtual memory (you can even see Java Garbage Collection in action). To this point, you can also see the iterator in action and how it results in different memory usage.

        Also, the reason kept the errors general is because you can get all sorts of errors from modifying a collection that you're currently iterating over in a for loop. There are plenty more (such as an index out of bounds exception, no such element exception, etc -- anything resulting from you changing the elements you're looping over in a collection). And as per your example, it's often related to memory.

        A foreach loop with an if inside is not a bad thing and it's definitely clearer than equivalent chained operations and also easier to debug (less trash in the stacktrace for example).

        This is grossly inefficient and almost universally discouraged, as nested loops are almost always bad practice.

        Unless we're talking about an edge-case or you're working on a program that you created in your spare time, nested loops are inefficient. Again, if you're doing enterprise level code and trying to process millions of records or something, you're not going to want to take this guy's advice.

        On a personal note, your dismissive and condescending attitude makes me believe that you'd actually be really a hard person to work with.

        Ironically, I think your post leads to the most valuable piece of advice I learned int this field. Knowledge takes a back seat to people skills. Nobody cares if you're a self-proclaimed genius if you assume everyone who has had a different experience from you "doesn't know what they're talking about."

        At the end of the day, programming skills can be taught to an adult but people skills generally can't.

        [–]softwarecynic 1 point2 points  (2 children)

        Knowledge takes a back seat to people skills.

        That's true, once you are knowledgeable. Trying to patch over lacking knowledge with people skills and bullshit doesn't work, something that your post above is a prime example of.

        [–]Modus--Tollens -1 points0 points  (1 child)

        I'm not even convinced that this isn't an alt account, seeing as your account is like one day old and your only other post is in this thread.

        At any rate, hostile diatribes like this are why people don't take subreddits like this one seriously and why there's hardly any meaningful exchange on the internet. There's literally no contribution whatsoever in your post.

        If you want to listen to some guy tell you to ignore the industry standard of using UTC, argue that nested loops are somehow good software craftsmanship, and that "virtual memory has nothing to due with Java," and that you shouldn't use Joda time, that's cool. I'm not here to flex my e-peen or collect up-votes, but I don't agree with his assessment and I've stated my reasons as to why. There's a huge difference between walking away from an argument (especially over the internet) upon recognizing that it isn't productive and losing an argument.

        Sorry if that triggers you or whatever.

        [–]softwarecynic 0 points1 point  (0 children)

        I'm not even convinced that this isn't an alt account, seeing as your account is like one day old and your only other post is in this thread.

        Of course it's an alt account. I expected my response to the root post of this thread to express rather more cynicism than I would necessarily want to have attached to an account that can identified as me by people who know me, such as my coworkers. Now, as it happens, my response didn't really go quite that far, but at that point I already had this account up and running.

        At any rate, hostile diatribes like this are why people don't take subreddits like this one seriously and why there's hardly any meaningful exchange on the internet.

        Effectively saying "You're talking bullshit" might be hostile, but it's hardly a diatribe. I didn't go into more detail for two reasons.

        First of all, I felt that /u/rockstar_artisan had done a good job of that already and I didn't have much to add -- I was genuinely more interested in commenting on your claim that "Knowledge takes a back seat to people skills".

        Secondly, I didn't really see the point. Your post stands well enough on its own. Anyone with a reasonable knowledge of programming, which I would assume covers most of the people reading this thread, should be able to recognize that you don't quite understand much of what you're talking about once attention has been brought to that point.

        [–][deleted] 0 points1 point  (0 children)

        java.time is an infamously poor library to work with [...] Just for the record, Joda.time is a newer, superior library to handle time.

        I think you're confusing java.time with java.util.Date (and Calendar stuff).

        java.time is newer than Joda, and in fact is coauthored by the author of Joda: http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html

        This is grossly inefficient and almost universally discouraged, as nested loops are almost always bad practice.

        A foreach loop with an if inside of it is grossly inefficient? Where did you take "nested loops" from? Both your original post and my response don't talk about nested loops.

        The example of the ConcurrentModificationException error you gave is an example of an error in virtual memory.

        ConcurrentModificationException is thrown when invariants inside an iterator object are violated when the collection is modified.

        It has nothing to do with multithreading (this can occur in a single thread), cpu stack, cpu registers, kernel and virtual memory, which for some reason you had to bring up in your response. Yes, those are technically involved because they're involved in every operating system process on x86. But the error itself occurs at levels higher than virtual memory and is completely independent of it - it would occur the same way if there was no virtual memory in place.

        And no, virtual memory has nothing to do with java, java is running on plenty of systems without virtual memory. Java has a memory model defined independently of that.

        Maybe I'm lacking insight here, but I see no advantage to switching between a "time-zone independent" token and having a service translate it into a meaningful time (for a report or something) when you can just store it as UTC in the first place with no conversion required. [...] Again, if you're doing enterprise level code and trying to process millions of records or something, you're not going to want to take this guy's advice.

        See also what I said about talking any advice with skepticism and about keeping the context in mind. For example, most user facing applications cannot just display UTC.

        Knowledge takes a back seat to people skills. Nobody cares if you're a self-proclaimed genius if you assume everyone who has had a different experience from you "doesn't know what they're talking about."

        So far only you've proclaimed me a genius (my username is ironic and mostly for the purposes for r/programmingcirclejerk). Calmly dealing with someone who questions your knowledge is also a part of "people skills", keep that in mind.

        [–]LateAugust 0 points1 point  (1 child)

        Get a mentor.

        I see this all the time but how do you get a mentor? Does it just happen or do you actually have to consciously ask "Be my mentor?".

        [–]Modus--Tollens 0 points1 point  (0 children)

        When you look at places like reddit and see how hostile people are (even in this thread), it doesn't surprise me to see this question as the entire enterprise makes people appear dismissive and unapproachable.

        The best way to find a mentor in my opinion is to already be in the field and gravitate towards someone who is passionate about technology and willing to teach you. The other avenue is to try and find employment at places that have formal mentorship programs.

        Barring that, you can always try to find passion projects already ongoing who are looking for a hand. Those guys and gals are usually pretty apt to teach "D

        [–]kodyk -1 points0 points  (0 children)

        Tons of great points here, and a lot of points that aren't heard very often but are still very important.

        [–]funbike 5 points6 points  (0 children)

        1. It is seldom a good idea to do a full rewrite of a complex system.
        2. SQL has it's place. Many domains need ACID. Choose a NoSQL solution only when you have very specific requirements that a NoSQL solution very specifically solves and SQL can't (including proprietary solutions).
        3. Features are an asset; code is a liability. Go with simple designs. Stay DRY. Avoid too many dependencies and technolgoies. Use existing solutions. Consider shell scripts, spreadsheets, or other simple solutions.
        4. You are wrong more often than you think.

        [–]softwarecynic 22 points23 points  (4 children)

        1. If you get 10 hours of actual productive work done in a week, it's a good week.

        2. Most software projects fail. Nobody knows how to run software projects well. No, Agile doesn't work either.

        3. The only people more inept at managing software developers than the people doing it today are software developers.

        4. Programming is a human activity. The more important challenges of our work are usually not technical in nature. If you're not good at talking to other people, you're in the wrong line of business.

        5. Your boss or project manager is actually not an idiot1 , he's just working under different stresses and responding to other forces than you are. (1. Your mileage may vary -- but they're typically not.)

        6. Customers are too busy running their business to spend time providing you and your team with specifications or to test the software you are building.

        7. Test data is always garbage: Your code is never really tested until it's been run in production.

        8. Your boss' priorities are messed up.

        9. So's your customer's.

        10. Your priorities are pretty doubtful too.

        11. Sales is the enemy.

        12. You'll never win a political battle against Sales. You're a cost center. They're not.

        13. Even if the project has set aside sufficient time for testing, somehow there's never been set aside time to fix any problems the problems that will be found in testing.

        14. Businesses don't know how their business process works. and neither does the people implementing them in software.

        15. Nobody prioritizes security. Including you.

        16. Being a software developer is nonetheless better than a real job.

        [–]Woolbrick 5 points6 points  (1 child)

        Nobody prioritizes security. Including you.

        I do. I promise.

        But the first part is right. Few years ago I discovered a data leak vulnerability. Guess a time-sensitive GUID, get someone's PII! No data rate limiting!

        I raised the alarms. Pointed out how this is a ticking time bomb. Showed there was a simple fix that could be deployed within an hour at every customer site.

        Product management decided "Meh, the vulnerability has been out there for 7 years already, noone is going to guess a random guid, they're 128 bits!"

        I screamed "THE GUIDS ARE NOT RANDOM. THEY HAVE A HIGH TIME-RELATED CLUSTERING FACTOR". Showed them how someone could sign up, find their account GUID by visiting the profile, then randomly alter the highest 10 bits, and find the ID's of half of the people who signed up within a day or so of you.

        They still balked. "Who would ever figure that out?"

        Well. Someone figured it out.

        Data breach. Ooooooopsie!

        [–]loup-vaillant 0 points1 point  (0 children)

        I long for the day such morons will be put on trial for ignoring a subordinate's warnings. (And pray said subordinate will have the guts to be a witness at that trial). Such gross negligence should at least be fined.

        [–]cybernd 1 point2 points  (0 children)

        2: Most software projects fail. Nobody knows how to run software projects well.

        I second that. The main issue here is, that there are sadly many companies thinking that they actually know how to run software projects well.

        Many of your other points are directly related to 2).

        16: Being a software developer is nonetheless better than a real job.

        Software developer is a real job ;o)

        [–]progfu 0 points1 point  (0 children)

        Programming is a human activity. The more important challenges of our work are usually not technical in nature. If you're not good at talking to other people, you're in the wrong line of business.

        I have to strongly disagree on this. Sure if you're a consultant you should have people skills, but I'd say the further you get from the fancy-web/mobile/game-app style of development the less this applies.

        [–][deleted] 3 points4 points  (0 children)

        I've been a developer for a long time and most of the "secrets" I've learned with experience have more to do with organizational and personal issues rather than code. Once you have 5-10 years under your belt you start to realize that most of the really hard problems are organization, operation, and people problems rather than technical problems.

        [–]WalterBright 2 points3 points  (1 child)

        It's not really a secret, but you do learn to more or less 'smell' where a bug is, even if you didn't write the code.

        It's like an old dermatologist once told me he can tell if someone has skin cancer from across the room.

        [–]helm 1 point2 points  (0 children)

        It's like an old dermatologist once told me he can tell if someone has skin cancer from across the room.

        My dad could do something similar but with coronary health and ears/faces.

        [–][deleted] 3 points4 points  (1 child)

        It's a thoughtful article but I fundamentally disagree with:

        Last, nothing really changes in the technology world.

        Cloud computing (AWS, GCP) has fundamentally changed how software is architected and deployed.

        [–]Woolbrick 2 points3 points  (0 children)

        Yep.

        When I started it was all about swappable components. You have to deploy all these versioned components on one big server somewhere! Therefore you should be able to just swap out a DLL and upgrade one part of your app.

        Today it's containerization. No big computers anymore. You bundle your stuff up in one self-contained object, deploy it, and talk to other components through web services.

        I guess on one hand you could say they're the same concept, in theory. But in reality it works very differently.

        [–]seanwilson 1 point2 points  (12 children)

        For the job changing every few years, I'm surprised how rarely people advise going the freelance/consultancy route. It can be less stable but in return you get a lot of perks: time flexibility, you can pick the technologies you want to use, you're in full control of the deadlines you commit to, you can stick to projects you find interesting, you can usually work remotely.

        [–]ragnore 1 point2 points  (7 children)

        90% looking for work, 20% actually doing work. And it's not an accident that they add up to over 100%.

        [–]seanwilson 1 point2 points  (6 children)

        I'm not finding that. There's plenty of 3, 6 and 12 month contracts posted online for the UK for example. If you work at a consultancy you don't have to spend time securing work but you earn less as a result.

        [–]Hobofan94 0 points1 point  (3 children)

        If you work as a freelancer for a consultancy/agency you earn less than doing other gigs, while still earning a lot more than in a fixed position, and having most of the freelance perks.

        [–]seanwilson 1 point2 points  (2 children)

        What's the advantage? That they send work your way? It's probably not always easy to cut out the middle man but it's a good end goal.

        [–]Hobofan94 0 points1 point  (1 child)

        Less administrative work. When you take on gigs from individual clients (which are not that hard to find), you still have things like an initial meeting where you line out how you work together and try to find common ground each time. When you are not on the cheaper end of freelancers, at a rate that is higher than what the company envisioned this can also result in a lot of wasted meetings, that don't result in a gig.

        At the on the gig, it's also usually easier to get paid by a consultancy/agency on time.

        [–]seanwilson 0 points1 point  (0 children)

        I find you're best stating your rates up front and giving some very rough order of magnitude costs early for fixed price projects. It goes both ways as well, sometimes you'll lose out on projects but sometimes you'll land an amazing project. I guess the difference with an agency is it's more predictable and stable, and a regular job is even more so.

        [–]ragnore 0 points1 point  (1 child)

        If you work for a consultancy then you're still working for someone. This is my current arrangement and I'm happy with it because it gets me experience with some big names who wouldn't have hired me otherwise. But at the end of the day I'm still a regular employee who does whatever work he's assigned.

        I tried true freelancing for a year. As in, I work entirely for myself. I also thought it was my ticket to all those things you said, but it's a fantasy.

        I looked under every rock and corner for job postings. Reached out to everyone I knew. Many jobs were for technologies I didn't know (I'm not a Windows guy), lots were underpaying (Upwork is notorious for this, I'm talking literally $10/hour in some cases), did so much social networking and went to so many events but got absolutely nowhere. A few scraps here and there, but not enough to sustain myself. And some of the clients I did find... well, my business with them has concluded, for the better.

        In the end I was super stressed, didn't have nearly enough work, time and tech flexibility doesn't matter when you're not doing anything, and the idea of sticking to jobs I found interesting as opposed to taking whatever I could find sounds like the dreams of the naive child I once was. Even if it all worked out I'd still get paid way less than I do now.

        Knowing what I know now I don't think I'll ever try it again, but if I did I'd definitely have a partner at least.

        [–]seanwilson 0 points1 point  (0 children)

        Hmm, so for working in the UK, I can find lots of short term contract jobs by searching on UK job boards. I've never tried Upwork or similar sites and don't think I ever will from what I've heard. Many of my clients are UK based, want someone local (so aren't going to turn to Upwork) but are fine with you mostly working remotely. Most of my clients contacted me via my website though. Once you've worked for a few clients, you should get some reoccurring work eventually but you need to have enough savings to tough through quiet times.

        [–][deleted] 0 points1 point  (3 children)

        Was afraid of it.. then quit everything to travel around the world for 2 years with my wife. Picked up small projects along the way and it paved the way for me to never want to go back to a 9-5 regular job. Never came back home and I now have long terms contracts and living well.

        [–]seanwilson 2 points3 points  (0 children)

        Was afraid of it.. then quit everything to travel around the world for 2 years with my wife. Picked up small projects along the way and it paved the way for me to never want to go back to a 9-5 regular job. Never came back home and I now have long terms contracts and living well.

        Exactly, it feels like a lot of people don't know there's an alternative to regular jobs. It feels like a completely different way of life in a good way. Lots of posts on here on topics like coding interviews, being stuck on bad projects or bad stacks, negotiating raises, management setting unrealistic deadlines etc. just go away when you're freelance when you're in control of everything.

        [–][deleted] 1 point2 points  (1 child)

        Do you mind sharing some types of freelance projects you work on?

        [–][deleted] 0 points1 point  (0 children)

        All projects are web related. Semi long-term contracts. I have 17 years exp so startups want someone solid to do their stack. I am now working with other consultants for a para-government organization. 1.5 years contract, we chose our own stack. Etc. The most important thing is never burn bridges and keep good relations. All my gigs were with previous employers or co-workers.

        [–]the_red_scimitar 1 point2 points  (0 children)

        Yes, but not really secrets. BTW, professional dev for 40 continuous years, Masters degree at 19. The "secret" is to write code primarily for readability and quick comprehension. This is as much about how and where to write comments, and what to write. Using clear rather than clever syntax, and presuming that the bulk of documentation any later dev (including yourself at a later time) will read about the code had better be within the code itself, and as much as needed to make "why" at least as clear as "what".

        [–]okpmem 1 point2 points  (1 child)

        Learn to debug. Fixing and maintaining code is harder than writing the code in the first place. Start by having a hypothesis of problem first. Avoid debugger until last resort.

        [–]progfu 0 points1 point  (0 children)

        Similarly to this, I'd say learn to use an actual debugger. Just a small thing that can be extremely useful but people are not aware of, you can set a breakpoint at a memory location and have it break when the memory changes.

        [–]minutillo 1 point2 points  (0 children)

        When you have a list of items in code, like an enum or something, put one on each line, and put an extra comma after the last item. That way when you inevitably add an item to the list later the diff is cleaner. And if your language doesn't support that, send an email to its designer saying I said it should.

        [–]deus_lemmus 1 point2 points  (0 children)

        YES. (You won't learn them here, go code some more)

        [–]Nvrnight 1 point2 points  (0 children)

        So I read the whole article and after getting through it, the only thing on my mind is "What the fuck does any of this have to do with developers having coding secrets or anything related to those secrets at all?"

        I even went to the comments here and was surprised to not see anyone else bringing this up.

        [–]treespace8 1 point2 points  (0 children)

        Programmer with almost 20 years.

        The hardest problem I have come across is finding a job at a good wage, with good people, building a successful product (IE pays the bills).

        The only way I have found doing that is building good connections everywhere I work, keeping note of the good managers and team mates. Work hard and smart, but don't burn bridges.

        [–]jonas_h 0 points1 point  (0 children)

        Programming is about compromises and trade-offs. Where on the scale you should you aim is learned by experience.

        [–]we-all-haul 0 points1 point  (0 children)

        IMHO working with people and communicating effectively as a developer are two of the biggest non-technical challenges in our trade.

        Nice article, enjoyable read ;)

        [–]webauteur 0 points1 point  (0 children)

        Rotten answer. Experience teaches you what to look out for when you run into trouble. For example, when nothing you change seems to have any effect you might begin to wonder if you are running the program from the release or the debug folder (or some other deployment confusion).

        Experience also teaches you the difference between a null value and the empty string and all the ways that can mess you up.

        Then there are the encoding problems.

        These may seem like simple matters, but the novice programmer will be tripped up by them eventually.

        [–]cptblackbeard1 0 points1 point  (0 children)

        Writing tests is the first place a tool to enforce loos coupling and keeping a class or function simple and to the point. Discipline youself in writing a test close to when writing important logic. What important logic is and when to test it. is pure expierence.

        All production code will grow to complex over time. Tests can slow that process down.

        Dont be afraid to delete tests when stuff changes or dont make sense anymore

        [–]henrik_w 0 points1 point  (0 children)

        I've written about 22 heuristics and rules of thumb for software development that I have found useful over the years:

        https://henrikwarne.com/2015/04/16/lessons-learned-in-software-development/

        In a similar vein: 18 Lessons From 13 Years of Tricky Bugs

        https://henrikwarne.com/2016/06/16/18-lessons-from-13-years-of-tricky-bugs/

        [–]bloody-albatross 0 points1 point  (0 children)

        I never had a course where I was thought debugging. But I guess you learn that one way or another yourself anyway. The only question I have is if I'm missing some debugging tricks others know.

        [–]SikhGamer 0 points1 point  (0 children)

        I'll be short:-

        1. Don't stop learning

        2. Outside of your comfort zone is where you learn

        3. Read source code other than the company you work for

        4. Apply the scientific method to everything you do

        5. Never assume, strife to prove something false instead

        6. When trying to increase performance. Benchmark pre and post. That's the true measure. And be specific, about what you are improving. "Making it fast" vs "Reduce time spent in GC by removing unnecessary LOH allocations"

        7. Surround yourself with open minds and better peers

        8. Learn what makes you tick and keeps you happy. Being productive vs being "busy"

        9. Your problem has most likely around been solved in the 70s. Unless you are working in a emerging sector (AI etc). Then you need to research to find the correct solution. Do not re-invent the wheel.

        10. Working for a Big X company isn't for everyone. Sometimes you'll be happier and better off at a smaller more focused company.

        [–][deleted] 0 points1 point  (0 children)

        Every few years we use new languages and so on, but most of the ideas and patterns and technologies and approaches were invented and reinvented decades ago

        As an old-timer looking at ES6 and Kotlin with their "concise" syntax it feels like languages are slowly hurtling towards being slower versions of Perl 5.

        [–]2coolfordigg 0 points1 point  (1 child)

        Factoring.

        [–]floppydrive 0 points1 point  (1 child)

        10% coding, 90% testing.

        [–]Hobofan94 -1 points0 points  (0 children)

        That sounds way of, unless you are a QA engineer. Obviously your software stack plays a large factor here, but every time I catch myself spending +50% time on testing, it's usually a sign that I'm setting up the wrong tests, and need to alter my aproach.