Don't overwork. Seems obvious, though it's not only still prevalent in America, but more important for our field. Working extra hours has rarely benefitted me either in quality of work or in company treatment. Nobody cares that you put in extra hours. In fact, don't expect your boss to care about anything you are doing even if they are generally benevolent.
Your success is mostly dependent on your personality with appearance as a close second. That's not to say you won't have big wins with the projects you work on, but a lousy programmer won't get fired if they are charming and everyone likes them. The more I refined my social skills, as well as my grooming, the more my minor achievements would get overinflated by my peers and the more they would overlook my mistakes. It's just a cruel fact of life, but at least it's something most people can actually address.
I've never understood why more people don't ask for the interesting, fun, challenging stuff. I've always done that, and been glad I did.
Programming talent is useless if you can't communicate. Because your main job as a company grows is to grow the people around you, not cranking out more code. Communication overtakes pure coding skill the moment more than one person works on a project.
It's not about "trumping talent", it's about the fact that communication is part of the talents you need.
This is really untrue. On the surface, code might look the same between a beginner and a senior developer, but the decisions underlying the code will be night and day. Beginners will solve the problem of the day directly, with no care for introducing complexity and no willingness to reconsider past decisions.
Coming from the other direction, just because it's straightforward to you doesn't mean it's obvious to everybody else. Try to be patient.
Experience certainly shines bright in architectural and design decisions.
I think the parent's point is that no one's code should be considered sacrosanct; all of us can make mistakes, and all of us, even the senior guys, will end up writing some ugly hacks just to get something out the door on time.
More junior programmers should not be afraid to make a pass at improving something, nor should they try to emulate their peers' styles or behaviors without thinking about and processing them, lest they internalize bad habits. If a junior dev notices an error, they should point it out, instead of assuming the senior developer's code is beyond reproach. They should understand that once they get added to the resident Wizard's project, they're still going to have to deal with the reality of a production application, which means shortcuts, impurities, bugs, and mistakes. The principle of Linus's Law depends on developers who are willing to call out mistakes and at least prompt a discussion about the tradeoffs.
This doesn't mean that senior developers won't be much better at writing maintainable code on a macro level. This is especially true because I've found it usually takes until upper-mid-level for developers to really get an appreciation for simplicity and avoidance of technical debt, and to register that you're actually better if you can do more with less. (n.b.: speeding up a computer program is just making it do less)
It pisses me off how I keep having to rewrite/resolve this particular problem I have of deploying a photo sharing site based in a poor network area.
One day I feel satisfied with the work I've just done, the next day it is garbage and I do it again a different way.
Faster but not fast enough.
Then you get this huge block of code and feel this heavy weight like ahhh.... Slash and burn...
Am I doing this the right way? What is the right way? Look at other major sites, why don't I achieve that same performance?
It is nicer to start over but is it a waste?
Answering this really depends. I think I would start with "what do I hope to get out of this process". Are you doing this to learn? Are you doing it to grow a user-base? If it's a user-base, is this the biggest problem preventing your growth? If it's learning, is this the most interesting problem for you to solve?
The Dom loads just over 1 second, but things are still waiting to show up(js?) So I'm thinking of building empty templates like "Hey something is here don't worry."
I don't know. I'm actually not sure what progressive loading is. I currently use that blur-up method but I've seen those sites that use a technique where the photo is super pixelated (large pixels about a quarter of an inch or 1/8) before loading the high res. I think that is true progressive loading but don't know what it means with code.
I do build a template and spit it out according to what is requested, but then a JS function runs to "fill in the blanks" with a secondary call for the missing data. I should probably get rid of the images formatting (based on aspect ratio) to fit into the tiles. I don't know...
Pushing that hate for legacy code to your own self is important, as it as a good motivation to improve (for us narcissists at least).
Which is why I'd say, unit-test your code, or TDD, or something. When you look at that crap months later, your mental model of how it all works has completely eroded, and only the test suite is left to preserve your expectations as they existed back then, preventing you from wasting a lot of time stepping on your own toes while you re-grok the big picture, if you have to make a change.
> The boundary between a beginner and a coding rockstar really isn't very great unless you are getting into the realm of computer sciences, like machine learning.
I don't agree with this. I didn't spend 20 years learning nothing, as it were.
Same general quantity of perspiration either way.
For me that's the craftsmanship in software development - shipping something I'm proud of.
My main thing with TDD right now is - how do I avoid writing tests that are too tightly coupled? I've gotten burned in the past, not even doing TDD, with tests that "know too much" and end up being more hassle than help.
Any good resources on TDD and general testing strategy that anyone can recommend?
The trick is to omit implementation details from testing, because implementation can change, but after all fact(4) should return 24 no matter what.
So it's useful to think in categories of contract given unit should fulfill instead of testing everything for the sake of testing.
1) Just keep going. Experiencing the pain of less-than-ideal tests is pretty much the best way to learn. It also frees you from outdated dogma about testing.
2) Maybe try testing at different levels? I got into testing by learning to write big slow acceptance tests for a particular user experience and small fast unit tests for a particular module. This helped me see what each kind of test was best for. (Maybe your "big tests" are written in Cucumber and automate a web browser, maybe they test an HTTP API, that's up to the kind of work and environment you're in.)
3) Watch this video "Boundaries" by Gary Bernhardt: https://www.destroyallsoftware.com/talks/boundaries
You aren't wrong, the state of unit tests in the wild is dreadful. Many were forced into creating tests by management decry, others just think they know what unit testing is. Sometimes the latter are even unit testing advocates.
Remember what a unit is, it's not a class or the method, it's the unit of behavior you are testing. In practice this basically means whatever you are asserting.
Stick to the single assert principle and keep tests small. This doesn't mean only one assert statement, but only one behavior. Often asserting that a function returns an object will one test (it didn't return null), the details of the fields that object contains (like did we format "LastName, FirstName" properly) will be different tests. If you are asserting "LastName, FirstName" in 10 tests then 10 tests will break when that behavior changes. Only one test should break.
Always have a setup method that creates the owner of the unit and any of it's (mocked) dependencies. When a behavior is added it should take less than a minute to add the test for that behavior (assuming the test fixture already exists).
Do that and you're writing better tests than 95%+ of the industry.
I view TDD as a workaround for a lack of a REPL.
When the code is finished, the tests can be written or polished but writing them before any code is just one variation of testing.
def test_sum():
assert sum(1, 2, 3) == 6
def test_sum_no_args():
assert sum() == 0
def test_sum_negatives():
assert sum(-1, -2) == -3
etc, and then you write the function.This means you only do the "REPL" testing once ever for each case - and you can rerun the tests for all future changes. If ever type the same function + args into the REPL more than once - you have done redundant work and are wasting your time.
Likewise if you're in the habit of writing tests after your function is made - it shows you haven't put much thought, which means you haven't done the proper analysis of why the function exists, if the function is really one function or should be two functions, what arguments it can take, what it should return etc.
I'd say that's a pretty broad brush you're painting there with
But testing is important, for sure.
Every manual test you do of your code in a REPL is literally a unit test screaming out at you that it wants to live in your suite.
Automate that and you have a unit test.
Do it right before you write the implementation (forcing you to first consider how it might work, not a terrible exercise), and you have TDD.
Every unit of code should be smallish, focused, and with the absolute minimum of external dependencies. That will make it easily unit-testable and far more maintainable long-term.
There's finally empirical data emerging that TDD is a labor-saving device... Look up the Nagappan paper. (There's more than that now, though, that's just the most famous one.)
Also, as someone else mentioned, watch the Boundaries talk by Gary Bernhardt. Amazing.
I respectfully disagree. My experience says the difference between a beginner and a really good, experience coder, is HUGE, and not only on fields like "machine learning" but in everyday commercial systems.
Unless, of course, your platform is something like Java where everybody is crippled to an extreme degree.
That is, if you get 400 people on a room, tie their hands and their feet, they most likely dance with the same skill, their dancing experience notwithstanding ...
You just proved this by picking on Java.
This is all in the presentation. The point of putting in extra hours is not to get more work done, but to appear at least as busy as (but preferably busier than) your peers.
Most people can't tell if your work is good or not. They can only tell if it looks like you're working hard, and if they like you/find you personable. For most people, "butt in chair time" becomes the biggest factor in their perception of how hard you're working.
Since you're providing good advice about appearance, politics, and popularity, I'm sure you've registered this. We should just clarify for the people who are "4 years in" that "don't overwork" means "don't actually overwork", but do take care to ensure everyone in your office thinks you're a hard worker.
I'll add to the chorus here and say this is not only untrue, but so untrue as to be absurd. By all means caution against hero worship and remember that even those with exceptional talents are human, but don't misinterpret that lesson to mean there are not vast differences in quality between a beginner and an expert.
* Salary compression is real: most companies are not going to keep giving you raises to match what the market would give you for your skills. They would rather you leave and take all of the institutional knowledge with you than pay you the amount you could get elsewhere. Even if that means hiring someone else at market value.
* Don't get comfortable at a company to the point you're not getting new experiences and learning new skills. Don't become a dinosaur.
* Even if you don't want to become a manager, when the time is right and you have the right skill set, demand a title with "architect" or equivalent in it. Titles are B.S. but people listen to developers with "architect" as part of their title. I insisted on the title and now I'm being recruited for much higher salaries even though I had the same responsibilities as a "senior".
* Good local recruiters are your friends. They can tell you salary ranges for a job and they do a lot of the hard work for you.
* know how to calculate your contract rate if you're doing contract work. Your rate will be different if you are a W2 contractor vs a 1099 contractor. Take into account self employment taxes (1099), the lack of PTO, the time between contracts etc.
* Whether you are a contract or perm, realize that you are still your own company. Your employer is your customer. Do you your best work but never feel a sense of loyalty that keeps you from jumping ship for higher pay. They don't have any loyalty to you.
moc.liamg AT hcselftrebor reverse that.
However, sometimes even horrible recruiters can help you get a foot in the door somewhere. This is especially true with temping: you show up and start working right away with a minimal interview process. It's a great way to subvert corporate HR machines and get in the door and start making connections.
If you're looking for a new job of the type that recruiters may have, submit your resume to them and let them spam it out for you, but be firm with them when they want to waste your time by sending you to something that you know is a dead-end, or when they're trying to set up "check-ins" or other meetings that don't have a client/potential employer in attendance (do note that most will want to meet you once to look you over and make sure they won't be embarrassing themselves by sending you to an interview, but once the relationship is established, resist further recruiter-centric time waste).
I'm cautious of the word "Architect" — even though I've had it in my job title in the past, and still believe that it can mean something. Unfortunately, it's also a word that's inserted into so many unrelated jobs titles (Enterprise Solutions Architect, Information Architect) — if you need to get beyond senior, and have influence over the wording of your title, then Principal and Staff are useful words — until they too are devalued
It is easier to get "hired" for new technology stacks because some people in the company already know you, instead of random HR guy that doesn't care about technologies used in side projects, only what was used on your very last project at work.
There is certainly no one-size-fits-all advice here!
>They don't have any loyalty to you.
Companies preach "family" and "loyalty". DO NOT BUY INTO THIS MENTALITY. They're not going to hesitate to fire you if it means they can maintain their bottom line.
and
>Even if you don't want to become a manager, when the time is right and you have the right skill set, demand a title with "architect" or equivalent in it. Titles are B.S. but people listen to developers with "architect" as part of their title. I insisted on the title and now I'm being recruited for much higher salaries even though I had the same responsibilities as a "senior".
Title's probably aren't going to be given without some other political reasoning. They have to be claimed. Same goes for "Director", "Head of", and "VP" titles. Titles are rarely assigned based on merit, so stop trying to earn them.
Additionally, I'd like to add the following advice:
Don't take compensation as equity these days. It's the same as taking your salary based on lottery tickets. Especially heed this advice for "nothing" equity offers of ~1% of common stock. It takes a really large exit for that 1% to turn into something meaningful for you. AND that's assuming there are scraps left over for the common stock holders.
Indeed. It's great to love your work and even your job, but never forget that this love is 100% unrequited.
My god, that's a spot-on piece of wisdom if I've ever heard it. Some titles like Principal and Architect can be earned through hard work and exemplary performance. C-level titles and Director/VP almost never operate on merit.
If you have to wade through traffic to get to your place of work, figure that time into your rate.
I'd add one more - if you ever get a good client (freelancing, even when you are full time) keep them happy. A client who doesn't come up with billion changes, pays on time, doesn't micro manage etc is really worth working with, even if the work itself might not be super interesting.
If you tell your employer you're leaving for more money and they get angry (assuming you didn't just consume a bunch of money in training), that's a sign that you made the right move.
A manager once asked a director for a training budget for his employees.
His director asked "what if you train then and they leave?"
The manager replied, "what if we don't and they stay?"
I would be careful with this advice. It might get you a cushy job and a higher salary at bad companies, but I think it's bad for your career in the long run.
In my experience most "architects" don't do any real work while cooking up a bunch of "best-practices" that sound good in a vacuum but either fail completely or create a big unnecessary mess when it comes to actual implementation.
In my experience, real practitioners who are actually worth paying attention to usually have the title "Lead", "Manager", "Director", or "Principal".
I would rather be called a "lead" than "principal". A "principal" is seen as an individual contributor, an "architect" is also usually an individual contributor but could also be someone who interacts with various departments to get stuff done.
It's easy for us programmers to become fixated on using a newer JS framework, a slightly tighter Java loop or the latest cool language. Took me a few years to realise that even though I care a lot about those things, other people do not. They are interested in the outcomes, not how it got built.
I'm running my own business and building things for myself these days. I use vannilla JS on the front-end and Java 8 on the back. Since I gave up chasing the new cool tech I have built a bunch of stable systems that have been great, well received, products.
If you become someone who has a history of shipping things that work, you will do a lot better than someone who knows how to write hello world in every JS framework.
The above comment does not absolve you from doing cool things, it's just that the cool things should align with business interests. No yak shaving. Sometimes writing a one-off script will take 30 minutes, and doing it by hand will take 10. Do it by hand.
I'm not particularly prolific, so the number of ideas I have far outweighs my execution so far. This is mostly due to ADHD and other issues which I'm working on fixing, and while contextually relevant is not my point.
This lack of prolific-ness means that I have a literal tower (it's rather intimidating) of wanting to build cute but objectively not so useful routines simply for the sake of building them.
I realize this is essentially the foundation of creativity, but I have a hard time justifying doing these things as I take a very long time to execute anything.
So, the ideas file themselves away - and surface when I'm trying to design actual things I'd like to build. And I get horribly distracted with doing X or Y a certain way, or I get carried away with how I can build Z out like this or that idea I had two years ago...
My problem is focus, I think, and mental partitioning, which I'm not good at. Does anyone have any suggestions for how I can do that?
My current solution is to have a backlog and spending time to prioritize them. I'd focus on my top priority, and continue writing down new ideas as they come into my mind. When I finish with the top priority, I re-evaluate to find out where the recent ideas fit in. I'd also look into reading about the agile methodology.
If you're like me, ideas come in very frequently. Embrace your creativity and ambitions by logging them. But try and shift your mindset to thinking about what is actually necessary for the final product.
If you want to add or alter something, that would be a new project.
Otherwise, you will never finish a project.
And yes, Agile is the best, because it's of the mindset that the Product is iterative!
You will have to find a way to develop the capabilities of your brain(working memory, long term memory, task execution and completion, focus and accuracy). You will have to do something that you have been evolved to do which is to have a creative outlet (Dancing, Music, Art) to develop those abilities. There has to be a task where you have infinite focus/hyperfocus, that builds a higher ability. In a sense you don't have to do something that is hard, but something that comes natural and something that grows.
The sequence of steps and motions that are required for dance, movement of muscles to precisely line up with the notes of a song, to reproduce the form of a drawing/painting all require some sort of mental partitioning. These things are all interrelated. I personally have only scratched the surface, because things become infinitely complex I have to decide what is the most important develop. If your lucky enough to be creative and logical these abilities will bleed into each other.
Also on the tower of ideas-- it's not a to-do list, you don't have to commit to every idea that flies through your head. Your ideas are a great resource for you to reach for any time you need it. A lake of ideas you only need to go fishing in when you happen to want to.
On the other hand, sometimes you're automating for reasons other than time savings. Maybe reproducibility or auditability.
However, there are special cases where you are exposed to a new technology which enables new outcomes.
I was fortunate enough to blunder into using the Web in '92 and Java in early '95 and they were tools where the "how" did matter quite a lot...
[NB I haven't touched Java in a dozen years or so]
I mean if you have a problem to solve and you have a choice to use some old tech that you already know, but it is going out fashion, and some new one, then the choice of the newer one improves your employability in the future. For example, I guess in 2000 there was not that much people with 5 years of experience of using Java in production, but those who had it, had to have pretty good chances to easily find decent job.
Of course there is a risk to bet on wrong technology, but at least you keep learning instead of just using ageing tools and becoming more and more disconnected from the current state of the art. It can be as scary as this https://news.ycombinator.com/item?id=11886753, a story of a guy who successfully solved business problems and delivered products with jQuery for a long time and then eventually found that he was out of demand because businesses started looking for people with experience of using React and he didn't have it.
When I've recruited I've always tried to assess the candidate on ability to get things done rather than knowing a specific framework. I'd look at how deep their knowledge goes and see if they can ship stuff - if they've been using jQuery but I need React then I'm not too fussed if they've shipped quality products using jQuery and have taken the time to learn pretty deeply how it works, the keenness to learn and ability to build things should easily translate to React and I'd rather have this person that someone who has skimmed the top of React for a few Hello Worlds.
I would hope and prey that interviewers would take a similar approach, if they are just ticking off keywords from your CV then it's a pain.
I think if anyone wants to go down the route of using Spring, Play or similar then you MUST spend the time learning it in pretty deep detail. I've seen so many people with "Spring experience" on their CV who can make a webpage appear using the tech but as soon as something goes wrong or they are asked to do something a little different they are screwed as they don't know the framework well enough.
I only use vanilla Servlets and my own stuff because I have been building up my own libraries and ways of doing things over time and I've been burnt enough times with old-school frameworks (like JSF and Seam) that just add so much unnecessary work and ball-ache.
I like to write the fewest lines of code possible and also use the fewest dependencies possible. I find that plain ol' Servlets gives me that for most of the stuff I do.
Perhaps I will try to use vanilla servlets for one of my personal projects. I'll have to start reading the docs!
The thing you will find using Java for a long time at any company is you eventually end up with your own framework / stack.... Yeah sure there is some underlying DI or Web framework but a majority of it becomes your framework and workarounds/plugins/extensions for whatever DI/Framework you choose.
I used to to think this was a terrible thing but these days I think using less dependencies, autoconfigure magic, and even using older technologies such as the Servlet API are just easier to maintain, understand, debug, stable and surprisingly easier to train new folks on.
This doesn't match my experience at all. Only really ossified organizations get to this state, even in Java-land. The amount of abstraction I have needed to put on top of Dropwizard in order to do literally everything I've ever needed, from websockets to web pages to file service. The underlying Jersey and HK2 system is simple, well-documented, and straightforward when I've needed to extend it, but these extensions are restricted in scope and easily testable to boot.
I see no benefit, in 2017, to using servlets directly. It's certainly not going to be easier to teach a new hire through look-at-the-code or look-at-our-minimal-doc instead of pointing them at the existing documentation and examples of best-in-breed tooling.
I'm not saying go use the Servlet API directly all the time but you damn well should know it since almost all the others build on top of it (including most of Jersey).
Particularly Servlet Filters. It seems like every framework has their own take on onion processing a request but servlet filters are actually easier to write then say some Spring framework "Advise".
As for Dropwizard... You do know its built on top of all the new JEE stuff like JAX-RS. I am willing to wager it will die and be replaced with something else... but those underlying javax specification stuff (like JAX-RS, servlet api, etc) are still going to be around.
You should know those underlying standard APIs.
The funny thing about you mentioning Dropwizard is it basically started as someones else stack built by mixing standard libraries.... something companies do all the time.
> I see no benefit, in 2017, to using servlets directly. It's certainly not going to be easier to teach a new hire through look-at-the-code or look-at-our-minimal-doc instead of pointing them at the existing documentation and examples of best-in-breed tooling.
Until shit breaks, or doesn't fit your exact requirements or the project dies, etc, etc, etc and believe me it does happen in which case you will need to know the lower level stuff. But yeah don't reinvent the wheel.
This.
If you want to use the JVM, one: use Kotlin over Java, it is a strict superset and a better development experience across the board. Two: evaluate something like Dropwizard (or even Spring Boot) well before you go near servlets. JAX-RS is not perfect, but it's a lot better than whatever you will home-roll. (Again, been there.)
Using your words if "using a newer JS framework, a slightly tighter Java loop or the latest cool language." doesn't improve the business value of what the customer is getting out of the product, it gets a very big NO.
I became very much against "cv building driven programming".
For greenfield applications, chose whatever the customer ask for on their Request For Proposals, or suggest modern solutions if they leave it open to proposal reply.
On existing solutions, deployed for several years on the field, actually measure what it brings in regarding business value. Either in terms of reducing project costs thus improving profit, or improving customer UI/UX thus improving the value the customers get out of the product, specially if it helps them to improve their profits.
What I am against is just adopting tech that doesn't improve anything, sometimes even causes products to be abandoned or removed from the market, just for the benefit of a few devs improving their CVs.
I have taken part in a couple of projects where it actually happened. Architects were busy chasing the new shinny instead of delivering what customers actually cared about. In the end the product was canned.
How do you know what improves what if you don't use it in anger?
There are many ways to research new tech without touching the current product development.
Sometimes it is better to be the turtle than the rabbit.
Especially in the Javascript world, it's such a new field that new techniques are being invented regularly. I've seen old backbone applications that are essentially frozen in time feature wise, because the code is so cumbersome and coupled together (by the framework's design) that it becomes impossible to add new features without having to refactor/rewrite the entire thing.
I agree, if you have have a finished product that won't be getting many new features at all, then leave it alone. But if it is an ever evolving product with new use-cases and features being dreamed up regularly, that application should probably be re-written many times over.
As for CV driven programming, here is a real case from a long gone project.
Dumping a fully working and battle tested Perl scripts for application installation in several flavours of UNIX, for Groovy based ones built on top of Grails.
It really improved the business value of those customers having to deploy a JVM, executing scripts slower than before and what was a simple set of CLI commands turned into starting Grails and navigate via web pages uploading files.
Learn to enjoy your work as that's the only way you'll make it long term. If that means spending a little extra time to write an efficient algorithm or structure your code efficiently v.s. just "getting it done", then do so for your mental health, not for the company.
You see, we're craftsman at the end of the day. We all want to feel like we are contributing quality work, and often that conflicts with the business's priorities. Take pride in your work and you will find it easier to show up at the desk each day.
—Stephane Faroult, “The Art of SQL”
Solve real world problems. Doing elegant things is very difficult because the real world is much more convoluted than theory.
Do a few things in depth. Don't jump at the latest thing every few months.
These are great! I would also add: be certain that the organization shares your values. If you really care about code quality, elegant solutions, etc, you'll have a frustrating time working at a company that doesn't prioritize those things.
So a software company as opposed to working in an IT department - programming and solving problems that really _aren't_ interesting?
That's one of the main things I crave these days (and I think it would make a big day-to-day difference) is to work at a software company as opposed to a company who leverages software.
Does this mean that you salary isn't increasing, or that you aren't valued at all?
I'm curious how most people receive or handle (or if raises are even a thing)
I don't work at a software company, or even a traditional "tech" company, but I write the software that powers our most profitable product. Since I'm the odd-man-out, and the higher-ups love org charts, they stuck me in the IT department. Net effect: IT just became a profit center and everybody in the company knows it.
Would that be the primary product of your company, or something that empowers other employees to work faster, and push _their_ products more easily?
I've been blessed by having experience in several, very different kinds of applications (web apps to avionics). Over time, I've realized the specifics of the problem at hand are more-or-less irrelevant to my happiness. I'm looking for something that's sufficiently technically challenging, where I can be surrounded by honest, friendly people, and make decent money.
This is very close to my real goal as well - but CRUD apps seem like the norm lately :(
This is THE big difference between S/W dev and IT. For 20 years I worked in the former, and for the past 10 in the latter. No question about it: IT is hell. Theirs is a never-ending mission to reduce the cost of moving data and being "compliant" with often-meaningless ever-excessive corporate standards (and forever meaningless MBA/CIO fads and groupthink).
Worst, in most businesses, IT doesn't have a respected mission. Ii provides an infrastructural service (a cost center) that other C-suiters dis as no more important than HVAC and sewer. IT appears on their radar in only two ways: 1) when something breaks and info clogs up or stops moving, and 2) when the budget is revisited and interest in IT cuts are reinvigorated.
Since nobody else in the corp. respects IT's mission, senior mgt. compels the CIO to adopt meaningless surrogate goals because IT's actual mission isn't sexy enough. So for the next six months IT adopts "Platforms" or trains half the staff in Six Sigma, or outsources, or insources, or promotes of whatever other CIO groupthink initiative is in vogue at the moment.
So yes, work somewhere software is valued, unlike IT.
That describes exactly the IT department in my company.
"Hey aren't you in IT can you help me with my computer issue"
One of the things I dislike the most is being referred to as "The IT Department".
The only place where I've seen IT being highly respected.
I fear I'll be hammering out poorly-spec'd features to the beat of another department's Gantt-chart for the rest of my life.
Because I bet you that you could find some if you switched from targeting straight dev roles to something else that is part of a SW org.
Any suggestions on alternate roles to look for? I'd worry that just because it's a software organization, it doesn't mean I wouldn't be filling their own version of cog in a cost-center.
So time spent using X is great, but just saying "I can learn" and giving an example of how you're able to learn is often enough. Then just look at X enough that you know the gist of it, have a small little sample project in your github account, and you'll be good enough that someone will hire you.
These people should focus on improving their credit, cutting expenses, and building up savings so that they can take the salary hit that will get their careers on a better track for the ~20 years until they're eligible for retirement.
Alternatively, these people can go in through a social backdoor. Befriend a powerful person at a company you'd like to work at and demonstrate why he needs you. If he has authority to set salaries, he will likely do everything possible to accommodate your higher-than-market salary, even if he can't get you 100% of the way there.
But beware: overpaying an employee is the best way for a company to trap him/her. Do everything possible to not become dependent on a rate you can't easily command somewhere else.
Alternatively, just put yourself out there. You don't need to be great, just find a job a little closer to your goal.
The website provides a decent in-browser editor, or you can write in your own and paste the solution. You get a few data points for expected output, can write up to 10 of your own primitive tests (although I tend to use asserts). Your solution is automatically evaluated afterwards, because it has a bunch of unit and performance tests written for it. When your program fails on small correctness tests, the website says what was the wrong output and what the correct output should be like. VERY nice.
The language used to describe problems is a bit obfuscated and maths-like, but I treat that as extra challenge. You certainly don't have to remember much from your university or high school to get started. It is important to understand and rephrase what they are asking of you.
no pain, no gain.
I interview for backend engineer jobs. I notice a common theme in the interviews: efficiency. They are very concerned with transactional throughput. They optimize everything from the services layer to the database for trimming every microsecond. At a past interview, the people wanted me to talk about the efficiency and implementation of various data structures: nothing exotic, just garden variety queues, stacks, lists, and hashmaps. They quizzed me on threading issues. One guy got into various indexes in a relational database and then jumped into TCP vs. UDP questions. In my most recent interview, the guy started by asking me the difference between optimistic and pessimistic locking. In my IT job, I never deal with locking issues: they are all abstracted away. Two-thirds of the way through the interview, I remembered and circled back to the question. However, the damage was more than likely done. A person who deals with those issues daily would never forget. But, I know what to work on for the next interview.
I understand your predicament. It’s deadening on every level when you’re doing work beneath your capability and interest, but you don’t have the necessary knowledge to get through an interview for more interesting jobs. Hopefully, the observation I made above helps you to target particular areas to successfully navigate an interview.
Companies who base their interviews on CS curricula generally just end up only hiring people who've graduated recently enough to remember it (i.e., their staff ends up being junior because they're selecting for something that's, ironically, an anti-indicator of experience more often than not).
I work at an SV software vendor which sells to big enterprise IT groups. From what I have seen, firms are starting to take their IT groups more seriously.
[1] http://a16z.com/2016/08/20/why-software-is-eating-the-world/
I've done both and I can't say one is better than the other. I've worked on software products where marketing couldn't figure out how to sell it and kept changing the core functionality. Or where the CEO kept shoving his ludicrous ideas onto development. I've worked on rewarding IT projects where I worked very closely with the users and was very happy to see my work help them perform their day-to-day jobs. I've also worked on slog IT projects where the users had no idea what they wanted and we kept churning.
After 28 years, I ended up preferring working close to the actual users.
Check and check. There's also my personal favorite: marketing informs the dev team they've just inked a big contract with a tight deadline for features that were never discussed with the dev team. "We kinda told them we already had those features but hadn't released them yet. Can you guys build that real quick like?"
This is key.
However, recently I read Developer Hegemony[0], which seems to describe a path for IT developers to also have rewarding careers.
My current thinking is that the Agile philosophy definitely contributes both to successful projects and to satisfying careers for IT developers (Agile came primarily from that world of software development) but only when developers and users are equal partners. That generally only happens when the developers are independent consultants who can speak the language of business.
However, I do think that the original signers of the manifesto were onto something. My recommendation for people is, rather than learning an official methodology, that they go and read the writings of the various different signers. Get an understanding of what it meant for them at the time that they signed the manifesto.
Martin Fowler has commented that one of the other names they thought about calling their movement was "conversational software", in the sense that software development process was an ongoing conversation between the developers and the users of the system.
The point I gleaned from the book I mentioned was that (in the general case) the power politics of most IT organizations prevents the development process from every being a real conversation.
As I understand it, many of the signers were independent consultants at the time of signing (or helped lead IT consultancies) and could speak the language of business. It seems to me that perhaps this put them in a more "peer" relationship with the business stakeholders, and allowed the development approach to be more conversational.
Very true, but the company culture also needs to be right in order for this to really take hold. There's also the fact that the work and schedule will likely be more demanding. This can be a positive if you enjoy the work, but a big problem if you dislike unpredictable hours. When the company's primary revenue source is software, you will have to work extended hours at some point or another to solve critical business issues.
Once you have developed the necessary software skills in a "software house", in my experience, the best thing to so is to get stuck into a particular domain, where the company needs software developed (not IT), but is not the main business. These jobs and contracts attract the best $, but also in my experience, highest job satisfaction - you are not just a cog - well, less so, IMO.
It was slightly better, since people understood software's value, and Ops was shared between the devs and IT. However, maintaining that sort of culture always felt like a constant battle. Management often slipped into IT = cost center.
In fact, my job officially became bridging this gap as an IT Business Partner. I don't think I did a very good job.
If you really need to make software (like I do), make your own company and license/sell your work instead for >500% more than what would be your salary.
You should blog about some of this, changing names and obfuscating to "protect the innocent" so to speak. Also, read up on the Gervais Principal if you have not :)
Frankly, one of my favorite things in the office was to emit bubbles of incomplete information to individual persons and observe who gets to know that piece of information, mapping alliances at work - they were oblivious of being tested, always triumphant they knew better and it was just fun to simulate a clueless person on my side just to understand how did they exactly operate. Try it, it's fun and a quite harmless "game people play".
Yes, the reality of life is that it's not a meritocracy or even within a stone's throw of it. There's a fine line between acknowledging the reality of it and succumbing to it. The abyss gazes also.
But in a way it's been eye-opening, seeing this darwinian play go on, it confirms a lot of my theoretical understanding of evolutionary psychology, I find it quite fascinating. Not only that, but just observing it shows you how to improve in this area.
But from what I've observed, most people are completely unaware of this side of things. A certain personality seems to be affected by this "issue", and that personality seems to correlate quite highly with caring deeply about their work, pursuing excellence in their field and so on. But alas, no-one has written more clearly on the topic/ psychology of corporate politics than Michal O. Church, I do recommend reading his essays for those affected by the issue (even though he has acquired a bad reputation around these places, probably because this is a sensitive issue).
The "one ring to rule them all" approach...
The hardest part about this (for me) is finding a project/product to begin working on.
I'm assuming you came to that sort of idea while working for others (which seems like the best way to learn).
Why not? What's stopping you from learning?
1. Find people who are great at it and be interested in how they do it. I think of this as learning to read good design before you write it. They may be interested in how you do what you do as well. 2. For me, one of the most productive steps was learning the basic mechanics of the bootstrap CSS framework. It did not make me better at designing beautiful web pages, but it did help me make something minimally usable (i.e. not repulsive) that lets me get my ideas roughed out. With a few days of learning, you may be surprised by what you can do. 3. If the best you can do is a cookie cutter design that lets you get started, congratulations! You can get started! What I mean is, I have felt what you are feeling, and there are ways around the problem. Good luck!
Finding other programmers or like minded people is the hardest part it seems for me.
The last sentence is actually not bad advice though.
Even if some completely broken companies, this was good advice, it would be a recipe for a pretty pathetic existence.
From where I stand, software engineering has been an absolute boon. I have friends who are doctors, lawyers, consultants, traders, writers, salespeople, marketers... On nearly every metric -- pay per hour, amount of bullshit I deal with, variety and interest -- my job beats theirs. I started coding when I was 10 years old because I was a big nerd who wanted to make video games. I never, ever thought I'd make a top 3% salary 5 years out of college doing something I love. I'm tremendously grateful for that. I've been really successful by just being good at what I do, and that's mostly what I've seen other successful people do around me.
At the end of the day, unless you own your own labor, someone else will be profiting off of it. The lower down on the ladder you are, the bigger the gap between the value you produce and your income. But that being said, software is not such a bad place to be relative to other fields.
Wrong. I've been at it for 30 years. It's not all roses, but it's still pretty good. The key is to be doing something where 30 years of experience is worth more than 5 years of experience. I'm in embedded systems, and the experience matters there (to enough people, even if not to everyone). Web programming? I'm less convinced that it matters there.
> Move to a management position quickly...
It is my explicit career goal to never become a manager. I've seen what that looks like, and I don't want it. I might make more money if I did, but it's not worth it.
And if you think that the answer for "your brain stops working" is to go into management, all I can say is that I'm glad you're not my manager...
In my case, I'm pretty sure that I wouldn't be better than the ones I've been under (maybe I would be better than one or two, but not the majority). I'm also more likely to get fired as a manager, due to a tendency to say what I think.
If you're a better manager than the managers you've been under, you may be of more value to your company as a manager (even if you hate it). I may be selling myself short, but my value as a manager could be less than zero...
Yes, when you die.
Children are much better at learning new spoken languages, but by your logic no adult should even bother trying to learn a new spoken language.
There is no future in software development as a job
How can you make such a blanket statement? Software is a more lucrative position for more people now than ever in history. You want to be a manager?? Who will you be managing?? Programs that write other programs??Call me a philistine, but I don't really believe we will ever get the natural->logical language mapping perfect enough to obliterate the need for developers on a massive scale. New languages beget new possibilities, which companies want to employ people to exploit, and so on.
Higher-level languages have "obsoleted" the task known as "programming" over and over again, to the point where there will often be 4-5 "automatic programming" layers between the code written by a person and the code that a physical machine executes. It's been 35+ years since your average developer would write machine code directly (i.e., without depending on an "automatic programming" environment (aka "a compiler") under the covers).
There will always be a need to translate natural language into logical language.
I guess we will see how this pans out in the end...
Perhaps we are moving to a day when all programming will occur verbally, and each programmer will be paired with an Echo which he verbally instructs as it writes a program. But we will still need a person who is assigned with converting natural language to machine language, including reading in the contexts and assumptions necessary to make assumptions that are almost always correct.
That's the part that I don't see how computers are ever going to be able to beat humans on. You can't squeeze blood from a stone, and if the data isn't there and isn't in any of the spied-on data collected by all the listening bugs all over the house and all the location bugs carried in a person's car and pocket and all the network bugs on the person's computer and ISP, and so forth, the computer won't have the data necessary to furnish the desired response.
Conversational language will not have the necessary precision without special effort being dedicated to expressing ideas in a logical, mathematically-valid way. The people who expend that special effort are called "programmers".
IMO the only hope of a programmerless future is one where the language has meshed to the point that every conversational statement is a valid program after the NLP's macros have been expanded or whatever, and the computers understand this with a 0% error rate. A world where a master programmer reprogrammed human language to be computer-native. I don't see us getting there.
In other words, initially intelligent app builders will have very limited capabilities. As research advances, those capabilities will increase, in a snowball effect. At some point you'll be just talking to your phone and maybe touching screen here and there when making most web pages/apps, and all will be assembled from those building blocks. I believe we can now finally see a dimmed light at the end of the tunnel.
It's a looong way from tools like that to a state where a CEO can ramble on his vision for some app in 100% natural language into the microphone, and clever AI figures out all the blanks and automatically programs it for him.
It has not happened yet in the general/business programming field thanks to:
1. Software and automation being applicable practically everywhere (and also in part thanks to bubble money) - the field is still growing at a mad rate.
2. Business problems being less conducive to algorithms and AI. For example, try coming up with a good AI which can figure out how to handle an edge case in a supply chain app. The AI would essentially need to understand humans.
Currently the "art of programming" is a gift to a few. But if you look around you, almost everything people do is some sort of an algorithm, i.e. sequence of steps affected by inputs. ML will allow grasping some very difficult concepts which our brains can do naturally and help automate them, making those algorithms easier.
Ding ding ding! I agree with most of your advice, but this is the heart of it. People are very basic machines. Your job as an employee is ONLY to a) make your boss feel good and b) make your boss look good.
Protesting this is simple naivety. The sooner you internalize and accept it, the better off you will be. I have met multiple men who've lost everything at retirement age because they were naive and allowed themselves to be lulled to a false calm by slick workplace politicians. These events are _not_ pretty.
In software, there is a natural merit barrier to performing even the minimal job functions that can allow us to confuse it for a meritocracy. This is why slick MBAs are reluctantly forced to accept people with basic hygiene problems inhabiting corners of their offices. But mistaking this for actual respect for merit is fatal faux pas.
This is a simple reality that most of the rest of the world was forced to accept during their first jobs out of high school. Software engineers are spoiled, and far too many of us allow it to go to our heads.
>There is no future in software development as a job.
You're getting some push back on this because it's not really universally true. It depends on the individual's goals and ambition. You absolutely can spend 30 years as an employed software developer if you're happy with where that leaves you (and a large number of people are, and there's nothing necessarily wrong with that).
However, if you want to be more than an employee/pawn, if you want to make decisions, if you want to get more than a pittance of the proceeds -- you must accept and realize that your field of operation must be human psychology, and it must be correctly applied in its various forms (politics, marketing, etc.).
The sooner this is accepted, the better. Literally just in the last couple of weeks, I watched a multi-million dollar company with dozens of employees get wrested away from a competent (if complacent) engineer by useless, image-obsessed political hacks.
The kicker? That's not the first time it's happened to him.
Do not let the small successes that people are forced to give based on merit go to your head, or you'll end up like him.
Your code will be in production either much longer or much shorter than you think it will. The 5 lines of code you spend three days perfecting will be replaced in a week, and that one-line 3am hack will be out there for ten years.
A good walk around the block will help you solve a problem faster than staring at code.
Find someone smarter than you and learn from them. The corollary is if you're the smartest person in your area, you're more likely to stop learning.
What the customer needs is rarely what they say they want.
You will derive more long-term benefit from finding an answer yourself than finding that answer on Stack Overflow, at the cost of time. When time matters, at least try and understand why the Stack Overflow answer is right.
Don't be afraid to question a decision you don't understand, or don't like. At best, you'll get either your mind or the decision changed. At worst, you will learn something about your co-workers.
There's never enough money, time, or domain specific knowledge.
Office politics matter, regardless of how much you wish they didn't.
Maybe. I think the other side is find someone smarter than you, but less experienced, and teach them.
You learn much more from teaching than being taught.
If you're at loss of finding smart adults, find some children ; they're probably all smarter than you, in the sense of finding good questions (which is much more interesting than finding good answers; finding answers is just work, finding great questions require inspiration. A perfectly good example of a good question is: "why is the sky blue?").
The issue I have with this is finding that person.
A guy wrote a blog post about it (can't remember name), he hired a couple people for a half hour each until he found one he liked.
Alternatively see if there are any meetups in your area (meetup.com is great for that).
That said, teaching will not typically help you learn something new, though it will help refine the knowledge you already have.
For example, answering "Why is the sky blue" will give the chance to refine your own understanding of refraction and how that interacts with air, but it's unlikely to guide you into learning about quantum mechanics.
True, but that depends on assuming the person teaching is really only interested/aware of an answer that deals with refraction, and that the median mental model most people have isn't close to understanding the mechanics of refraction. I've noticed that the levels of abstractions we employ are all affected by these sorts of questions, perhaps the same question a year later would afford one the chance to unravel a particular layer assuming the layers above it are sufficiently saturated in understanding :D
On that note, I was surprised to see this comment when looking through the source code of the now-venerable program traceroute -
"Don't use this as a coding example. I was trying to find a routing problem and this code sort-of popped out after 48 hours without sleep. I was amazed it ever compiled, much less ran. [...] Van Jacobson (van@ee.lbl.gov) Tue Dec 20 03:50:13 PST 1988"
Absolutely agree! You have no idea how much I have learn from reading the official documentation of whatever tool I am using vs a basic stackoverflow answer with little explanation.
I'd like to extend this to include designers, non-technical cofounders, and non-technical colleagues.
I had a situation just recently where I built out a new front end interface for a new feature I had just built. There was a particular work flow that I had carefully laid out for a specific task that involved rearranging items in a list. Not having a 100% explicit spec, I was free to improvise within constraints.
So, I built this interface out and tested it.I then handed it over to my colleague who is responsible for green lighting new features and such. Well, my colleague decided that the interface should be completely rebuilt for better usability. That's fine. No problem, that's my job. Though, it would have been nice to have a spec up front so I don't have to throw away hours of work.
So, I convince my colleague to write out a very detailed user story so I can make the interface just how they want it. I get the user story and I completely rebuild the interface. I then hand it over to the same colleague and they say that the interface still needs improvement. I'm confused at this point because I followed the spec to the tee. They explain how they want to improve the interface and their explanation sounds almost exactly like what I had implemented the first time! Needless to say, I was a bit ticked off. That said, it's best not to make a big deal out of it as I am getting paid for my work and I don't want to make my colleague defensive.
Luckily, I had the old version in version control on another branch so I was able to pull it back into the working branch and make some minor tweaks.
Moral of the story: Non-technical people don't really know how to express what they want to a technical professional. I'm in no way implying that non-technical people are inferior. They just don't understand the job of a technical person and all of it's implementation details. The same issue applies to fields other than software development. For instance, it's difficult to express how you want a contractor to build something if you have no experience building something.
You will also run into people that have no idea how to do your job and have no idea how to express what they want, but also insist that your job is easy. These people are idiots. You just have to humor them until they inevitably fail at their own jobs and go away.
A bit of a tangent here, but this is why I could never bring myself to use Scala. At least early on, their pitch for the language was frequently backed by code comparisons where many lines of relatively verbose Java would collapse neatly into just a few lines of Scala.
For me, at least, I had the realization that even if I figured out exactly how a particular block worked, revisiting it later would be a huge challenge in terms of re-learning. Java has proven itself to be a lot more readable and self-explanatory.
This has really helped me out with some nasty bugs.
0) Nothing is too hard to do, no matter how much those doing it might seem like towering titans many levels above you, or how out of your reach it may seem. Nothing is too hard, there are only things that take time, and things that take more time. If you put in the work, those titans will be your peers before you realise it. Of course, you can't do everything. If you want to put in the amount of work needed for some things, you need to focus. That means deciding to not do some things that you want to do.
1) No-one who is serious about programming gives a shit about language wars, they're for fanboys and spectators. People who get shit done are too busy to spend time on that. So don't sweat what language you choose (too much – there is still such a thing as the right/wrong tool for the job) and especially don't worry about the people insulting it.
2) If it's not constructive practice, you're wasting your time. I spent too much time - literally years - spinning my wheels, writing code but not getting any better at it. Make sure you're reflecting, make sure you're improving.
3) (related to #1) seriously stop worrying about choices and just get something done. You don't get things completed by worrying if you're using the right language/framework/library.
Unfortunately I worry that this advice would send me down another bad path and I'd probably need to add on something like:
4) All that said, some languages really are limiting, either in what you can do, the level of concepts you will learn, or straight up teaching you bad habits. Likewise some libraries / tools / frameworks are actually bad. While you should definitely avoid trying to optimise the last % of productivity, you should spend some time to make sure you're not using something highly suboptimal. If after reflection you believe you are using such a language/framework/etc, then broaden your horizons. That doesn't necessarily mean rewriting your current project, maybe do a toy project or some exercises in something else.
For everything in your tech stack - find out the sweet spot use cases and the ones where really you should use something else. For example with databases - don't repeat your data (aka normalization) is common - when does that not apply?
Spinning your wheels would be things like trying new languages, frameworks, etc. for the sake of just trying them out. It's like going to a car dealer and test driving without any real need or intent to purchase - literally spinning wheels :) You might be fooling your brain that it is learning when you are really just trying something new that is nearly the same as something you already know.
More here: https://codewithoutrules.com/2017/04/17/learning-without-a-m...
This approach scales from the tiniest pieces of code to whole systems. If your last loop was a simple `for` loop, try writing the next one as a call to map function. If your last loop was implemented as map, write a simple `while` the next time. If your last app used Postgres for persistence, use Redis or CouchDB for your next one. If you're comfortable with MVC, use MVVM for your next project. If you're fine with dynamic typing, try using statically typed language or dialect.
Seriously - do it. Nobody is going to say anything to you: they all do the same to stay relevant, even if they know it's not the best strategy for a team as a whole. Make it your policy not to repeat yourself and only fall back to the tried-and-true ways of doing things if there are external circumstances which put you under some great pressure.
After a couple of years of this, you'll accumulate most of the techniques and skills you could ever need. The techniques and skills I talk about are transferrable between tech stacks to a certain degree, are impossible to learn/master quickly (no matter how intelligent you are the amount of information is simply too great) and really matter in practice. That knowledge is what differentiates senior programmers from others.
Anyway, good luck!
Four years in I'm hoping the OP has seen a pretty broad range of different styles and approaches and is now ready to hone their craft with smaller improvements, and is no longer struggling just to get something working so they now have some extra energy to put towards maintainability and overall system design.
It might be better to try to define and refine a consistent style that can be applied to an entire project, that way you have to evaluate all the options, and do everything intentionally, but also you're not sending the next dev back to the syntax manual every time they try to read a new function.
But simple things are being done differently anyway, all the time. There's too much variation in how you can code anything. The most trivial functions, like leftPad, can have dozens of implementations across a couple of projects - each as correct as the others, some abstracted, some inlined. Above a certain proficiency level, programmers are expected to intelligently recognize leftPad when they see it, even if it's called `frobnicate` and is implemented backwards (whatever that would look like). How can you expect programmers to do this without them going through a large set of sample implementations? Are they going to wake up some day to realize they got enlightened and now have no problems with dealing with leftPad in any of its many forms?
I find the argument of "increased cognitive load" entirely unconvincing. Yes, the code should be optimized for reading. But, as every writer knows, how you write depends on who are you addressing. In other words, it's both insulting and counterproductive to write your code as if your readers are bird-brains with severely damaged hippocampus. Your readers are professional programmers who know their craft - possibly better than you do - so have a little faith in them!
And if by some miracle you don't have enough of those things, spend more time on HN ;)
Edit: Getting a mentor can be tremendously helpful. If you work at a company see if there's anyone you can get paired with. Someone more experienced is great, but even someone at your level is likely to know some tricks you haven't learned yet.
Alternatively, ask a friend, go to meetups, or you can even hire people online to teach you how to code (on freelance sites etc).
I got comfortable with the small subset of the language I knew, and then used those tools to try to tackle all problems. I eschewed some of the more powerful abstractions because they seemed complicated and unnecessary, and because learning them would take me longer than forging ahead with the tools I already knew.
What I didn't realise, and seems obvious in hindsight, was the time to learn those new tools was an investment. If I knew them, I would not only be able to tackle problems faster than I could with my current tools, I would also be able to tackle far larger problems than were feasible to do with such basic toolset.
I think a possible rule of thumb for when you are being limited in such a way is when you're hitting a ceiling - when there's a complexity point you can reach, but no matter what you do you can't seem to push past it to make bigger/better things, it's time to "level up".
Another possible rule of thumb is if there's some framework or library or technique that others seem to be using and you look at it and think "but that's way more complicated than how I'm doing it!". Maybe it isn't unnecessarily complicated, maybe that extra complexity is the "cover charge" for being able to create larger and more powerful software. (An example: using an MVC framework rather than a bunch of pages with in-line database queries and templating.)
1. That statistics and metrics collection is incredibly important even if you only ever use it via libraries.
2. That code performance doesn't matter if the code is incorrect or insecure. So much of my life in industry has been tainted with an influence to conform to the cultural norm of "fast is best." This influence and culture is one of the most counterproductive parts of our industry.
3. The industry is actually full of great people, but those people avoid most of the media hubs that projects have access to because a tiny slice of terrible people dominate discourse. These assholes set the tone for the entire industry, and should be ostracized and punished. It's not everyone, it's a thin coating of hate.
4. Corollary to 2 and 3, I wish I learned to ask for help earlier in my career. I wish I could go back to my younger self and take the chip I'd acquired working with government contractors.
5. Corollary to 4, I wish I realized that I should be reading academic papers and that the people writing them weren't wasting time. Much of what's considered modern state of the art is in fact 5-10 year old work out of universities and MSR.
0) Money. the big money is in projects that need help. E.g. CEO during your interview: "The last lead programmer flipped me off and our accounting system in small talk is broken." That's hard. But that is where money is.
2) errors happen. Do tdd - so you can go to that concert.
2) Be the go to guy. If someone needs something you better be able to help. Brushing someone off creates office enemies and will remove any hopes of promotion.
3) any idiot can write code. I can with one hand tell you the names of people that can take over a system with 500k of mangled code.
4) think win/win. If you are doing a project - work hard -win for the company, but also put it docker so you learn something too.
5) launch side projects. You should release something large every year.
I think a corollary to 0 is that if an organization is in trouble it will usually find a way to always be in trouble. It's human nature to think a crisis is always almost over, often it's only beginning.
For sure, taking over a troubled project is a great and honest way to make money, and I love sorting out tangled messes where the original developers have all left (hit me up if you've got one, email in profile!), but just make sure that the problem wasn't a chaotic or toxic work environment.
People and their interactions are more important than events and circumstances in terms of creating an environment. Some teams run on crisis and others run on collegiality. The direct and indirect benefits of a positive work environment are tremendous.
If you're not a founder, NEVER take equity in leu of salary. If they offer a competitive salary and equity, that's a significant plus, but equity as a portion of your compensation value is essentially a scam. if the company goes under or you're let go before the cliff (which is usually two years or more, a lifetime in this industry), all that money disappears: not true of salary. If a founder or officer alludes to houses, cars or other riches as a pitch to join their company run. Seriously.
Take the time to understand systems and infrastructure. Not every dev needs to be a kubernetes expert, but the big difference between a code monkey and a code assassin is that the assassin can deploy their own code to production if necessary. If you're a web dev and you can't configure nginx or apache, you have a gaping hole in your skillset.
Launching off the last point: learn to be competent with linux. Linux is the preeminent environment of the software world and it pays huge career dividends to be able to script, configure, compile, install and maintain linux software and systems.
RTFM. This is a big one. Don't skim. Relax and dedicate some time to a thorough understanding of details. You can save yourself an immense amount of time when working with a new library/framework/language if you actually read the manuals and understand what your tools are capable of, otherwise, you end up wasting tons of time brute forcing your way into a crude solution that may have been trivially and correctly solved by utilizing the tool's strengths and features where appropriate.
Not true. I'm self taught and I had very generous offers from the two of the three big names.
Screw spending a time to getting a degree just for the sake of it and build stuff.
I know it wasn't like that before, but times have changed and so have recruiters.
If the company looks that closely to academic degrees, it most probably doesn't know how to hire staff. I don't want to be the only competent person around.
> ([...] two years or more, a lifetime in this industry)
Where "this industry" is "startups plus websites". General IT doesn't move that fast, especially with regard to good tools and ideas. A carefully chosen toolbelt of things that are ten-fifteen-twenty years old is still stronger and more flexible than most of the new sexy applications programmers now use.
Well yeah, only in the startup world are software developers offered equity instead of liquid compensation.
- Languages and frameworks don't matter. There's a closed set of concepts they're all reusing. Especially if it's hot shit: that means someone mined ideas from 30 years ago.
- Most problems tend to fall not to cleverness, but to compute power and the right glue. See previous two points.
- Everything is a tradeoff, everything is a moving target. Programming is about the battles you choose.
Spend your early career, to the maximum extent possible, in well-run organizations surrounded by supportive, skilled teams, so that you can optimize for skill growth and (secondarily at first, but growing over time) for individually attributable impact/ownership.
Honorable mention: AppAmaGooBookSoft hire mere mortals, too, and mid-career salary expectations at them are $300k.
Interesting... I have always steered clear of such jobs because I felt I would be just a cog in the machine. It seems to me only a select few in those organizations ever shine (and most of them achieved their status before joining AppAmaGooBookSoft). Am I mistaken?
The main reason I mention it is so that everyone knows to aim for a package (compensation, skills growth, interestingness of work, life happiness, whatever) which compares to a clearly achievable outcome which tens of thousands of people of similar skill levels get offered every year.
Are you asserting that those five turn over a majority of their mid-career engineers annually? That's the only way I see the tens of thousands number being accurate.
As for "mere mortals", I think most of us realize these companies hire them. Hell, I've been interviewing for my company a lot recently and a number of the people from those companies have been underwhelming at best (some to the point of causing me to wonder how they got hired there and I didn't). The issue is that many of us have soured on the random bullshit in their processes and have decided to stop throwing ourselves at it. I think it is a disservice to the up-and-coming not to acknowledge that and for them to realize it is "realistic" in a similar way that hitting a number in roulette is.
What's your over/under for how many engineers AppAmaGooBookSoft will hire this year? Mine is 50k. I did a back of the envelope calculation for this last year but can't find it.
90% retention rates imply a 5 year survivorship of ~60%; feel free to take any of several thousand HNers out to coffee if you want to confirm what competent, worksmanlike execution means your 6th year pay package looks like.
Since the number is dominated by Amazon, who has a huge logistics contingent, I'm not sure specifically about engineers. I'd say roughly half of that total is engineers that have something to do with software (not necessarily software engineers). That bumps your number to over 15% of the total engineering headcount. I'll be conservative and say 25% of the engineers are not software (with most being in Apple and Amazon). Now we're looking at 50k being 19% of the total software engineers.
You seem to be talking about hired at all levels, while I was talking about only senior hires. In that case, I am closer to you than I indicated. My (possibly wrong) impression is that the majority of hiring by these companies is new grads and juniors, since that is what their interview processes are heavily biased towards. I put the total number of senior hires at 10k - 15k.
As for total hires overall, I'll buy either your total hires or your retention rate, but not both. These companies are not growing headcount fast enough to be doing that much hiring at that retention rate in software engineers alone.
I was addressing Patrick's numbers (50k software engineers per year and >90% retention rate). Your link provides evidence that the latter number is incorrect, which was part of my point in both posts. In fact, it demonstrates that Patrick's 5-year scenario is the exception rather than the rule.
(Of course, both you and Patrick can be right if the typical 5-year trajectory involves only well-paying jobs, even it's usually more than one job.)
I think 90% retention is (probably?) an underestimate. People tend to look at measurements of tenure, see a short number, and assume Google et al burn people out/have revolving doors. Instead, that's really a function of the still explosive growth we're going through (for better or worse; I say worse but who listens to me?)
(Which still serves Patrick's larger point.)
I would say it is a strange but not bad combination of being a cog + having autonomy. I feel like a cog in a very big machine, there are many other teams i interact with, but simultaneously I have more autonomy within my own business line than any other company I've worked in. I'm constantly asked to think of new ideas and ways we can improve our processes, architecture etc and have gotten to prioritise my own work on things that I thought were important.
I'm not sure if I'd say I'm 'shining', but I'm earning more money than I dreamed possible while learning from a lot of smart people, which lines up with pat's experience.
When I started out I had a horror of working in a large organisation. Worked for Ericsson for a year, but the size of it appalled me and I left. I've learned since that if you are smart and get shit done then you're probably best off climbing the ladders a big corp has, rather than churning out code for one small shop after another hoping they'll hit the big time
I spent at least five years chasing down "AttributeError: X has no attribute 'Blah'"-errors in Python at runtime, and came to think that this was what programming was. Three-or-so years ago I discovered Haskell, which transforms these types of errors into compile-time errors, preventing me from building the program as opposed to a sudden runtime crash.
I wonder just how many hours I've wasted doing this completely meaningless task. It's not really a problem while your programs stay small but, as they grow, I found it became the main source of time spent programming, taking away precious time defining the actual application logic.
Mind you, Haskell is fairly extreme in this regard, and I'm sure there are languages which take a similar approach, without the mathematical certainty of Haskell. But, as I've become used to the precision offered by Haskell, settling for something with fewer guarantees -- but more libraries and easier-to-digest documentation -- would feel like a great loss to me.
http://www.mrmoneymustache.com/2012/01/13/the-shockingly-sim...
Or are you making a large enough salary in the PNW/San Jose or something where you can put back 1-3 mil in 10 years?
I ran that calculator and while it says I can retire soon, I've always heard 25x income to be a much more reliable number.
* Listen to developers who have deep and abiding hatred for some technology that they can argue coherently (with a range of deep technical details, links to bug trackers, etc.). These rants are a gold mine can save you a universe of pain.
* Almost all good coding boils down to three things - choosing a less powerful language/approach, writing less code to do the same thing and looser coupling.
* All things being equal, take the job with the higher pay. It almost always means you're treated better in other ways, you work with better people, you work with better tech and on better code.
The important lesson for me was not to despair and not to get all preachy on the other programmers, but to see how to make the best of that situation. And while it was a real pain at times, I was able to be productive and get some real work done.
Also, if the only tool you have is a hammer, every problem starts to look like a sore thumb eventually. Do not stop learning new things. Both for pragmatic reasons, and because it helps keeping it fun. It doesn't mean one should use every shiny new thing out there just because. But without knowing what options you have, making the right choice is not trivial.
It seems tedious and slow at first, but it really isn't in the long run. It results in clean, organised flow of code & projects.
After leaving that company, I eventually discovered mercurial, and later fossil.
- As many people point out, the languages don't matter - something better and newer will come along, and you'll need to adapt, but that's not where programmers provide value - they provide value in understanding how to solve the problems that the business side is facing. It's easy to find someone who codes better than you - new grads, offshore devs, but it's harder to find someone who understands your business well and can solve the problems that it's facing.
- Always be learning, always be reading, always be innovating.
- If you can, contribute to Open Source and/or stack overflow, etc. People who interview you will do their homework, and you want to have a public presence that will help sell you.
- To me, the most important thing, is to try to work for an organization where you are the dumbest person in the room. It might sound counter intuitive, but if you are the smartest person there, who are you going to grow from? At the very least, when you look for a job, the people should matter the most. Obviously, pay, technology, commute, etc. all matter, but if you surround yourself with a good group of people, it makes work easier. The jobs where I was by far the most skilled and the most talented wound up being the jobs where the less-qualified people on my team became the biggest drain on my attitude and time.
- If you are going to go the management route - make sure that you get training. Can't emphasize this enough. Just because someone is a good engineer, and is able to self-manage and prioritize well, doesn't mean that he or she is good at managing other people. Just like you didn't learn to code overnight, you won't be able to learn to manage overnight. (That advice alone 15 years ago could have put me in a different trajectory).
In my experience, this can go either way. I worked for an organization where our team were the "lowest" in rank. The end result was:
1. Everything boring gets piled onto you because those senior to you have "better things to do to earn their high salaries"
2. You don't learn much from doing boring things.
3. There are enough boring things in an organization that if you want to take on more challenging work, you'll burn out (they expect you to keep doing the boring stuff - it's mission critical).
4. They were really not interested in your growth. When you hire a janitor for your business, you do not really care about his/her career growth. If you're in the bottom rung of an organization, they may view you as the janitor.
Occasionally people did rise, after an intense amount of effort. But most learned that the smarter move was to move to a different job.
Knowing where you are in the organizational picture is important. In my bottom-of-the-rung job, I solved more challenging problems that required more advanced knowledge than I do now. Yet I get paid more than those in my previous job, and career prospects are better.
We often fall into the trap of thinking solving challenging problems equates to better pay/career. But I suspect your position in the organization is as much a factor. When I changed jobs, I was no longer at the bottom, and I got to pass boring tasks to other teams lower than me.
My advice: From a career perspective, it's usually a bad idea to be at the bottom of an org (even if you have a PhD) - no matter how interesting the work.
Also, no matter how smart you are, if you're on the bottom, people won't listen to you. Simply by being a little higher in the org chart makes people listen to you.
Negotiate.
Read https://pragprog.com/book/rdbcd/behind-closed-doors
Identify and measure the output of your team. Track your performance by how fast your team creates value. Reduce variance first, then add speed, then more capacity.
* Typed languages while more complex are worth it (circa 12 years ago I was a heavy scripting language fan)
* Unit tests that heavily use Mocks are almost always a bad sign. Brittle tests suck. Don't increase coverage for the sake of it.
* Get it done and move on. Try not to obsess on little details that add no value.
* "It depends"
* NIH (not invented here) is not always bad. In general it actually is often better (ie invented here). Respect the previous engineers when you move to a new company. There is a reason why things were built the way they are.
* Almost everything can be done in Bash :)
Or perhaps you mean "strong typing"? Because Python is a "strongly typed" language: It does not do automatic conversion of types, if types are incompatible, an error will be raised. Which I agree with.
But it is a dynamically typed language: You don't need to declare types, and, most importantly of ALL, functions and containers (lists, etc) are not bound to a specific input data type.
I do think the combination of strong typing + dynamic typing is a great combination.
Also, amen brother on your thoughts about Unit tests. They have been greatly overblown these last years.
I have heard this a couple of times from some developers with similar backgrounds and I have typically found that either these emacs/vim developers are very disciplined and/or have not really worked with large teams.
Or the language hits their problem domain so well that the benefits of productivity and terseness outweigh safety (ie research/scientific computing) and or the projects are small.
But having had 15 or so developers working on a project before Typescript was invented I can tell you the pain was tremendous.
Using the same tool for build, test automation, deployment, sys admin, refactoring, etc. is valuable. Otherwise you are stuck with frothy and immature domain-specific tools that clutter your brain.
Shell is sort of universal in that C/C++, Go, Python/Ruby/JavaScript, etc. programmers all use it.
It's sort of like the idea of mastering a single editor. You wouldn't want to switch editors every year. Likewise I think knowing shell and Unix really well pays off over the long haul.
I like some of the features in the other shells but bash is ubiquitous.
It goes from simple things like being able to copy/view production logs in seconds (instead of fumbling through the file system) to writing DSL's in awk.
I'd go as far as to say we'd be better off teaching kids how to write shell scripts than any of the current programming classes or the "mail merge with word" classes that they get taught today.
Then you get past the surface ugliness and discover its power.
I agree that shell SHOULD be a first programming language. But I don't think you can teach it to beginners with a straight face. There are too many sharp edges.
I'm working on both a bash-compatible shell and a new language that aims to fix this:
It would be great if the first thing you boot up to on a computer is a nice programming language with the capabilities to do practical things like send mail, scrape the web, talk to hardware, etc. I think of "apt-get" as the standard library for shell, and it is unbelievably powerful.
I wasn't thinking they should learn programming as such. More that they should learn some various unix tools (grep/sed/awk/etc), learn how to combine them with pipes and learn how they can save the workflows in a shell script. Maybe some functions and variables but not if statements or loops. Maybe even do that in awk instead of bash.
I really love the blog by the way, any tips for putting one together like that? I'm currently replacing my node based abomination with a similarly minimalist one built with make, a couple of awk scripts and pandoc. I was thinking of going even more minimalist and putting a link to firefox reader mode on the page.
I can imagine a curriculum where you go from HTML (data) -> regex (patterns) -> full source code. One thing I noticed is that a lot of people who want to learn to program aren't that proficient at using a text editor and generally using a computer, and doing HTML first will solve that.
But I also think that regexes have the obvious problem of syntax too. I have taught regexes along with Python to non-programmers, and it works OK, but the material didn't demand too much. I think it was basically \d+ and one or two other constructs.
FWIW one of my goals is to combine bash, awk, and make, although this is sort of far off: http://www.oilshell.org/blog/2016/11/14.html
Awk is an OK first language but honestly it's worse than JavaScript, because you can't even return an array from a function. Also, functions can't be used as parameters or return values to other functions.
Although I suppose it has the advantage of being very stable and immediate, and not requiring NPM and what not. However JavaScript has the advantage of integrating with the web.
---
As far as the blog, it's a bunch of custom shell, Python, and CSS that I cobbled together over the years, and then wrapped in a Makefile. I use markdown.pl but I'm thinking of switching to CommonMark. I've made several static websites before so I copied the best bits, with not too much cruft.
It also evolved over the course of the blog. It looks really simple but there are some details that I spent awhile on.
(And honestly I wish Oil existed so I could write it all in one language, not shell + make + Python!)
In my game dev it took me a long time to let go of "but I need to create an elegant/clever solution that covers all my planned features rather than just what I'm implementing now". What that got me was a lot of unfinished projects with elegant solutions. When you have time to code, code. Not necessarily the first solution that comes to mind, but maybe the second. Now you can keep coding instead of being stuck. Let your mind percolate on the solution in the background while you code, and while you're doing other things later. It's amazing how many times the solution will present itself after you implement a couple different pieces that now need to tie together. Use the power of your brain's pattern recognition.
Yes, you will "lose" some time in refactoring, but the truth is every project I've worked on, one-man hobby up to multibusiness teams, has had refactoring due to scope creep or "we didn't realize this would be an issue until we implemented it."
It will take time to learn how much thinking vs coding to do (both extremes are bad).
Final bit of advice: don't listen to the opinions of people as to what is a good or bad language. Try them out, use the right tool for the job.
I don't know how others work, but I had a tendency to try to code the whole thing in one go. Now I build the skeleton and start fleshing it out piece by piece, with an end goal in mind. It's very iterative. Do the next thing, whatever it is, large or small. Build and test. Refactor if needed. Rinse and repeat. I have to have it roughed out before-hand, but it will almost always change a bit as I get into the nuts and bolts of it unless it's trivial. Now I adapt as I go. The design reveals itself :)
Almost-as-important: stay curious.
Apart from that:
- experiment, make mistakes, screw-up, accidentally do rm -rf / etc etc. Just make sure you learn from them :-)
- look at how other people have solved similar problems, perhaps what your colleagues have done at your job rather than just random github stuff so that it has more context. See if they did anything that you didn't think of (... or not!)
- learn the basics of key data structures and how/why they work (graphs, trees, hashmaps etc). Learn why they are cool, what the benefits are and where they could be useful, but remember the most important point and try not to be too clever and force them in where a loop would do!
- try to keep your interests/skills/knowledge fairly broad. I've interviewed people who seemed really good, but turned out to really only know about one specific narrow field (e.g. they knew everything about ReactJS/Angular/VueJS (for example), but did not know even the basics of how HTTP works or how to do a SQL join) so I've had to reject them. As well as programming, learn a "enough to be dangerous" in unix CLI, networks, databases, web stuff, basic OS stuff, storage etc.
- similar to above, try and learn another programming language after you are competent in one. The learning experience and different perspective will make you a better programmer in both languages.
- finally in a slightly more negative vein, the company you work for might be nice and might be friendly, but the company will have zero loyalty to you if it comes to layoffs/re-orgs etc. Don't stick around at a company longer than you know you should just because you feel like you "owe it" to them.
Have fun and good luck!
OOP is just a sliver of it and the typical ALGOL-based languages you're learning are a small piece of what programming can be. Learn functional programming now. Learn about immutability, referential transparency, and data-oriented programming. Even if you continue down the imperative, OOP path afterward, this knowledge will change the way you approach every design.
There is so much more to learn, and so much more I could reveal; you'll get there, though, and it'll mean more because you did it yourself. Keep at it.
Keep your software design simple, your code simple, your tools simple. Sure, it's nice to use new and shiny tech for your side projects, but real software should be done simply and efficiently.
Simple trumps everything else, but it takes a real master to know how to pull it off. Especially in the context of complicated software requirements.
During my career I've met very few programmers who are capable of doing this well. It's the true art of the profession IMO.
- software is just pure crap. Tools are crap environments are crap libraries and frameworks are crap. Nothing ever just works but endless nonsense and meta problems.
- career progression is shit unless you're really few of those superstars at an organisation that appreciates technical skills. Or unless you have other skills such as bullying ass kissing or office politics.
- regarding code itself. Code as little as possible. Code is very expensive so you want to solve your problems with as little code as possible ideally without any code.
- be aggressively lazy. Don't do anything that really doesn't need doing. Focus your effort on the few things that really matter. Remember hard work has no intrinsic value. Engineers in general don't understand this.
- don't be sloppy. The things you do code while you try to minimize the code the code you do write needs to be at least ok quality.
When I look back at that period, I think I enjoyed what I was doing but in terms of technical knowhow, I wouldn't change much. Of course I know more now than then but I walked a certain path and I enjoyed it. The process was part of being where I am now. So, I think I'm happy with it so far.
What, I would like to have had since then: A good perspective on how the business functions. More empathy.
I've learnt these over time and even in this case, I think learning these was part of life. I don't really feel like "I wish I had the chance to go back and change things". I just feel foolish about some things I did then but I acknowledge that at that time my level of maturity was different from now and even if I had more (relevant) information or ideas, I'd not have been ready to use them.
Finally, I'd say that as long as you tend to reflect on what you do and where you want to go, you'll do fine. Conscious and intentional incremental improvements take you quite far on the long run.
Good luck!
Other than that, practice, practice, practice. And get out of your comfort zone when you practice, don't just do things that are easy for you. You are only learning when it is hard and it makes you wonder if you might be stupid.
One of my best skills is assuming. I have to make tons of assumptions, and if I stopped working whenever I didn't know the answer for sure, I'd never get anything done.
Instead, I make my best guess. If I'm unsure enough, I'll also send off an email stating my assumption and asking for direction, but I'll still keep coding based on that assumption.
I am almost always right, and I get a lot more done because of it. Even if I'm wrong, it's going to be a lot quicker to rewrite what I've done than to have done nothing and have to do it all after I get the reply.
I'll answer a question you didn't ask, too: What do my bosses wish I'd known when I started?
That saying, "no," isn't a good answer. Never just reply "no" when someone asks if something can be done. Find out what they're actually trying to do, or suggest an alternate way to accomplish it that can be done.
That's terrible advice. If you're unsure of what you're supposed to be doing, you should close the computer and start exploring your options with pen and paper before doing more damage.
If you keep going based on assumption, you drive halfway across the country in the wrong direction like in Dumb and Dumber.
Sometimes it's better to do nothing at all than to inflict damage because you didn't know what you were supposed to be doing.
Basically, when I hit a roadblock that I can't get around by working on something else while I wait for clarification, my process is as follows:
1. List my options.
2. Pick the best one.
3. Send an email to my boss outlining the possible options, and note that I've picked what I think is the best possible option.
4. Continue coding and know that I might have to rewrite that feature if my assumption was incorrect.
If you're right, great - it wasn't a roadblock. If you're wrong, you modify or rewrite... which isn't too big of a deal, as you would have been picking your belly button lint while waiting for an answer anyway.
Stop feeling guilty for not finishing side projects (only finish the good ones).
Adapt not just your skills, but your learning techniques (you're not in college any more, and the learning landscape is evolving quickly).
Don't be overly loyal to your company, at least more than is rational (their loyalty to you is limited to shareholder return and their basic humanity). This isn't to say you should bail early (as you won't learn or ship anything real), but value your own career over the number of years you stay with one company.
Look ahead regularly: where do you want to be in 5 years? It takes 5 years to get somewhere (like front-end, back-end, kernel dev, UI designer, etc.). As this question EVERY WEEK, and do something about it.
Make good habits: your habits are your learning and productivity, this includes the wetware (i.e., you).
Yes, it is cool to know all latest features from language X or framework Y, but real work on a company is not only typing code.
Learn to get overview of how software architecture and development processes work.
Build your social skills to be able to bridge between technical audience and those not so technical.
Do not work in silos, make sure you get an overview of what everyone is doing, get domain skills on the business areas the product is targeted for, learn what customers actually do and want from the product.
You have to ask for more to get what you're worth. And it doesn't hurt to ask, worst case is they will say it's not in the budget (even then it's usually not a firm no).
The trick is during your review you have to say you want more. You have to present a case that you're worth more. And it's not even a hard or complicated case to make.
If you know what the industry standard is in your area and you're underpaid say "I think I deserve a pay bump of <gap + 5k>. The average rate for programmers here is <x> so I should be at least making <gap> and you just told me I'm doing a great job, so I think I deserve a little more than average."
In all seriousness I'm basing this on past experiences (both myself and colleagues). You probably deserve more than you're being paid. The company will easily pay more than they offer by a little and most likely by a lot (if you're a good negotiator and make a good case).
The key is: ask for more, justify by reminding them you do a good job.
1. To not worry about my code being judged too much. Everyone's code can be improved. The real art is to know the balance between good enough, and not contributing obvious technical debt.
2. Not being afraid to break things. (unit testing helps lower that fear, so is documentation, single responsibility principle, open closed principle etc)
3. Assume you will probably never have time to rewrite it.
4. Assume you will probably never have time to do a major refactoring on it either.
5. Boy scouts rule. Due to the above, just gradually make the code a little better everytime you touch it. You see something bad in the neighboring method? cleanup, even if you didn't write it, and make sure the unit test covers that (shows how unit tests are important. It's not just to test your code, it's to allow people to feel comfortable changing your code when you are not there)
6. Unit test (almost) everything on one hand, but feel ok to skip testing a function that does something so trivial that the test itself is just repeating the same logic. Also consider mutation testing over code coverage as a metric.
7. The obligatory - check your own code first before blaming others, Google everything, if something looks WTF, then you are either looking at the wrong server, have cache issues, wrong git branch etc... (9/10 of the times)
8. Use other people's code, avoid NIH syndrome, use open source (with the right attribution) and don't be afraid to try and contributing back to the community. Best code is code you never had to write.
If the problem is genuinely original to you, your best bet is to find the biggest leveraging factors(language, tools, libraries, etc.) and consistently lean on those to arrive at a solution fast, then pay down the resulting debt in dependencies, performance and gaps in UX later. This can actually aid in an R&D effort because reaching a clunky solution quickly will lend a certain maturity to the codebase and the problem you're addressing. But it means being willing to read and reuse code that you are personally uncomfortable with and know does not really solve the specified problem exactly. This is a revision-heavy process and it's antithetical to what many programmers are inclined to do - which is to get everything finalized in one shot, drawing on all the stuff they know is the "best practice" even if it's tangential to shipping.
The more you're willing to allow your code to be "knowingly wrong" in ways that are easy to call out and to return to later, the faster you can get to the stage when actually revising it has value. This is why everyone writes bad code yet some code looks better than others: the good code was bad code that solved the right problem, then revised.
- You must decide where you want to go next. The first thing you should think about is: three years from now, will you take the Manager path (lead a team) or the Individual Contributor path. If you choose IC, do you want to specialize, or you want to broaden your skillset and become more of a generalist? In any case, I would say work on soft skills, broaden your horizon (e.g. learn new languages, write front-end code if you do backend and vice-versa, etc) and learn one to three domains very well (look up "T-shaped", this is where you want to go). But focus on the part you will need the most for your next step.
- If you go for the generalist IC route, try to work as close to production as possible. That means: deploy your code, monitor what it does to the servers (or machines) it runs on in the wild, watch how real users use it. Also, it is time to learn how your tools (build system, programming language, OS...) work.
- If you specialize, pick something with a future, engage with the community, and if possible with Academia. Sometimes when I talk to engineers and mention I read research papers they think I'm crazy, but there is no way you'll be good at an R&D topic if all you do to keep up with research is watch videos and read popular science blog posts.
- Have fun. Don't burn yourself out working too much. Keep doing fun side projects, they teach you things you don't learn in a professional setting.
* What customers and clients _need_ isn't always what they say they need. Learn to drive at the underlying problem in your discussions with them, and don't focus on what they think the solution should be. While you should always accept their input for the latter as well, keep in mind that most of the time it will address a symptom and not an underlying problem.
* What a customer wants may be related to what they need, but this varies.
* Don't solve problems prematurely. Even simple bug fixes - what is the impact? Are you changing something used downstream?
* Don't assume good tests will always catch all breakages. If they did that, we'd never have to fix bugs.
* Don't trust your dependencies, vendors, platforms, or anything else to reliably inform you of breakages and incompatibilities. They're all run by humans and humans make mistakes.
* You are responsible for shipping working products. If you include a dependency and it breaks, you are responsible for finding that out before your customers do.
Using one or two new things on a project rather than 10 you'll be both more likely to get somewhere, and more likely to pick up the newer elements well.
-1. That I should have jumped in straight into Lisp from day one.
0. That popular technology does not mean that said stuff is the best, great, good, or even acceptable. Example: PHP 4.
1. That the industry raves about a seriously, seriously crippled and flawed language (Java)
2. That "Design Patterns" are mostly workarounds for the problems introduced by flawed languages (again, Java and friends); not great ideas to be proselytized.
3. That Object-Oriented-Programming is not only done in the way of C++ or Java, but that there are much superior ways to do OOP. (i.e. Smalltalk, CLOS)
4. That if you want to solve complex problems in a productive way, you need a multi-paradigm language. Strict-OOP languages or Strictly-Functional languages will limit you, unless the problem is really suited to it.
5. That the "Blub paradox" is real. Programming languages are not equal.
6. Real world (i.e. commercial, production) software should always be done by experienced people, not by juniors.
7. A seasoned (say, 8+ experience) programmer can done things 8 times as fast as a junior (graduate) programmer. I've seen this firsthand.
8. Dilbert -as others have pointed out- is a documentary. 8.1 Corollary: Pointy-haired bosses are real.
9. The customers will always think everything has been done using Excel Macros.
10. The salesmen are very important to the health of the company, so don't make fun of them; rather, make friends with them and help them get aligned to what the technical team is able to do.
- Don't get caught up in hype. Technologies go in and out of favor. Not long ago the idea of writing a application in JavaScript would have been laughed out of the room. Today the idea of building applications in Perl seems antiquated. The truth is it doesn't make a lot of difference which language you use, and no matter what you pick it will probably be less popular in 5-10 years if not virtually abandoned.
* Have tests but don't be crazy about it.
* Keep your development process as streamlined as possible.
* New languages generally aren't as hard as you might think and they might be the right tool.
* The right tool for the right job can make a huge difference.
I'm a hater of the sentence "use the right tool for the job". Nowadays, any language can do pretty much anything you want to do with it (except if the language has recently been created and is still in the early stages, e.g.: Elm?).
So then IMO these days what you have to do to choose your programming language is not ask what you're going to do, but know what you want to avoid.
So I use this rule of thumb:
Do I want to avoid paying licenses (or resorting to piracy if I'm in the early days of a startup and I don't want to spend money), then I choose a language and a set of tools which have open source implementations (compiler and class libraries) (i.e.: C++11 vs MS Managed C++)
Do I want to avoid chasing memory leaks for the rest of my life? Yes, therefore I use a language which has garbage collection (i.e. Java vs C).
Do I want to avoid painful evolution of my project, especially when it's getting larger (wrt easy refactoring and maintainability)? Then I use a statically typed language instead of a dynamically typed one (i.e. TypeScript vs JavaScript).
Do I want to avoid recent headaches I've had with other software projects in which concurrency was very hard (read: race conditions), then I choose a functional language (to achieve immutability, avoid side-effects, etc.) (i.e: F# vs C#).
And it's not that I ran out of questions, there are many more...But, did you guess it? The questions above are the most important ones you should ask yourself when choosing the next language to use/learn, in my opinion. And, did you guess it? This is why my current favorite programming language is F#: because you can avoid most of the pitfalls that you find in other programming languages in the industry, and you still can do pretty much anything with it.
I use Python for anything related to text processing or webscraping. I use Haxe for when I'm doing cross platform game programming. I use React for web UI / front end work. Erlang for distributed stuff. In each of those cases I've tried other tools and the ones I prefer now seem much more effective ...
I've never done anything in F#
- Don't use the next big thing before actually understanding the benefits only because someone else tells you to. (Looking at you, Angular and Docker!)
- Stay away from programmers who have strong opinions about certain things. Most of them can't back them up with skill.
I'm curious, what do you not like about Docker?
Generally containerization of our app was a good step at this point, but we made the mistake to also put redis / postgresql into docker, which obviously is an stupid idea if you're trying to scale things. On top of that, docker networking was a science on itself, and we didn't use any proper automation tools.
Docker containers kept running out of disk space / memory and it took a lot of effort to figure out where to place apps. In the end we ended up in the same situation as before, that some containers were on dedicated machines and the rest had a kind of hard limit on the max. # of instances per machine.
Our deployment process went from taking 2 minutes to ~10-15 minutes because of docker registry and extensive jenkins build scripts. It also needed lots of network bandwith to be transferred to the actual hosts. We had to regularly remove unused images because the docker registry or our docker hosts ran out of disk space.
Finally we changed our deployment process to incorporate docker hub because it was advertised as the premium docker building service. We paid for that service, but it took between 20 and 40 minutes to build our images. This was unacceptable for our use case because we needed to fix bugs near-instantly. Customer support from docker the company and their unresponsiveness towards our latency problems was another problem.
After the engineer in question left towards a very well-known european music streaming startup, we finally ditched docker and moved everything to AWS beanstalk. It does proper version management, config management, auto scaling and can be defined with a simple json file and some some straightforward cli tools.
The engineer in question was very excited about the technology, so we went with it. In the end it was a great learning on many levels, and I can really appreciate the kind of problems that AWS solves for you.
It was a nice exercise to put our struggles w/ docker into a coherent point.
Keep your work code as simple as humanly possible.
Do your experimentation elsewhere (using the time gained by keeping your work code simple).
Your future-self, your co-workers, and your client will be grateful.
Let's say you need an icon for something, but don't know much about design. Once in a while, try making it on your own. Learn about the pen tool, image formats, etc.
Let's say you need a simple SELECT from MySQL. Read more into how they actually work under the covers, in large-scale environments, or how they change for MSSQL / Postgres.
Let's say you need a particular jQuery function.. take a few minutes to read the source and see what it's actually doing.
If you take a few minutes each time you do something unfamiliar, you'll gradually build up a better understanding and larger skillset without having to put in too much effort.
Either expectations set by the developer, improper buffer added by the project manager, or lack of push back against the client.
Stop calling errors, bugs. They're not cute things that just happen because all software has bugs. Software has errors. Trust your instinct to leverage tools to manage complexity and reduce the likelihood of introducing errors. Lean on sound typing, formal specifications, invariants and property-based testing. Learn to love restrictions.
Remember: tests prove the presence of errors, not their absence. It's much more powerful to state, formally, what your software will not do.
Also be creative and play. Take an idea to its extremes and let the haters hate.
Programming is beautiful!
Going for a walk and thinking things through yields better code faster than iterating over it hands-on.
Frameworks are overrated and often a source of ephemeral knowledge and code bloat. Think twice before committing to a framework or a 3rd party library.
Also, picking a good name for a variable may take up to a day.
Another example is the latest release of C++, which is strongly typed but now allows for dynamic typing with the 'auto' keyword.
I assumed that my parent really meant to write statically typed, not strongly typed.
People tend to not say what they really want. Become good at finding the actual requirements. As a CS student, if there are requirements engineering courses, do take them.
For many projects implementation is the least important part of the project.
Professional conduct is worth a lot.
I wish I had known more about what was actually going on behind the scenes as my code executes.
In my time, I knew my knowledge was lacking, but being poor and relatively isolated I had few options. Today, factors conspire to leave new programmers largely unaware there might be problems in the first place.
Nowadays, we have way better tutorials that teach people how to use effective programming methods, but we're still failing when it comes to imparting the understanding necessary for programmers to make mindful decisions about trade-offs.
I also wish I knew more about persistence and communicating what I'm working on, it's something I'm still trying to improve. When I was just starting out, I was working on a text editor, but gave up because I thought it was superfluous. When I was about 16, I had made a pretty good game (in hindsight), but gave up on it because I thought it wasn't good enough. My life might have turned out differently if I hadn't been so shy and uncommunicative at certain points.
if you don't have a large team (who can help with bouncing ideas, etc), the benefits you get from using module ecosystems like npm or pip can not be understated.
Was it hard to switch out of it and learn a lot more?
moving to typescript from C# was pretty easy, and the semi-functional paradigm of node (Promises especially) was an interesting and caused a beneficial change in the way I architect applications.
Never used a package manager before moving to Node, so the overall quality of the stuff found on npm was surprisingly good. still find some wonky/crappy stuff, but a lot of high quality stuff for just about any functionality you need, and all for free.
C# would still be very useful if I need a single application to maximize utilization of a desktop CPU, but for the SaaS stuff I do now, NodeJs + many small servers (horizontal scaling) is good for cloud vm's.
2. Personalities matter more than technology.
3. Don't let people drive over a cliff, just because it's their responsibility. Remember, you're in the same car. In a matter of life and death (of the project, or the company) grab the steering wheel. Of course, you'd better be sure you know what you're doing.
4. Out of desperation, some people will sabotage you and then blame you for it. Sometimes there is nothing you can do.
5. Always maintain a good working relationship with the person you're working for, whether a manager or a customer. Chat more often, even if it is uncomfortable. Especially with idiots.
6. Some people will be afraid of you, if you have greater expertise. They need to be flattered.
7. Seek out and learn from those who know.
8. Notice I said nothing about technology.
--------------------------
Beware the changes in technology. I spent decades in an environment where saving a few bytes mattered, and C compilers were just okay. The coding style I developed is now obsolete in the era of gigabyte memories, and too hard to read. Change with the times.
* Own what you own 100%. Be proactive, ask questions so you understand context, and raise concerns along with possible solutions when they pop up.
* Help others when you can. If you are going to be in this industry a long time, your network of colleagues and friends will help you long past your current gig. They can help you solve problems and avoid bad technical choices and when you are ready to move on, they can help you find a new job. The kindness you show others pays off in many ways.
* It's easy to get emotional when you are passionate about a job or a project and that passion can quickly turn into anger. Before sending an inflammatory email, sleep on it.
* Learn the tools of your trade well. Know your editor, debugger, devstack, monitoring tools, deployment tools, etc. I'm a bit hyperbolic but the single best thing I did in the last 20yrs was learn vim well.
* Work hard but pace yourself. Put aside time for yourself to stay healthy.
* Enjoy the moment even when it's stressful. You'll eventually look back on your career and see that the highlight reel features some "against all odds" moments and battle scars.
* Keep learning
Various bits of advice:
1) Pay attention to the severance package when you sign your contract. When you join a company, you probably aren't thinking about what happens if things don't work out. But let's say you end up working there for 10 years, bad times hit, and you get laid off. You don't want to be surprised to find that you only get the minimal statutory limit. Some companies, I conjecture the larger ones, will have more generous severance packages.
2) Be cautious about choosing to work in "branch offices" which aren't involved in key decisions in products/features. You may find yourself limited in how you can grow, both in terms of scope of technical projects and scope of career path. This is probably a bigger issue if the region that you live in is not a tech hub like silicon valley.
3) When I was younger, I was completely focused on programming and "software craftsmanship". In fact, many of the problems in commercial software development are people problems -- team co-ordination, process improvement, empowerment, motivation, etc.
I was dead set on building entire products, it's why I loved programming. It was why I love lego. But in hindsight it would have been a better use of my time to work on smaller projects and ideas. As almost nothing ever got finished before I was working on something new. I have very little in terms of a tangible outcome from that time period, and it extended beyond those first 4 years.
Now I wouldn't want to work on a full product before I knew I had all the larger parts finished first. I wouldn't want to work on those larger parts before I knew I had the smaller parts those larger parts depend on first.
Programming with this mindset has provided me not only with endless work to do. But less stressful, more satisfying, easily digestible work with semi regular tangible outcomes.
* that there are too many things to build and too little time, so don't code for the sake of coding, but solve problems and touch more lives
* that I could have supplemented my coding skills with business skills, and built something that made me money
* that life is short, and coding isn't the only thing to do
---
Bonus tip: strong CS fundamentals, math > new hip language, new framework
The biggest wins are where you make a good decision that avoids an entire class of bugs or an avoid having to write an entire layer of software. These are also the hardest wins to measure.
Pick something you are genuinely interested in and learn it very, very deeply. Don't jump around constantly or you won't have insight.
One thing I wish school taught was code maintenance. Most of the code you write has a shelf life of a few weeks as you fulfill your assignments. Bad decisions only come to haunt you after months.
You need to watch for new technologies that matter, but 90% of what is new will not matter. One technique I've seen work is to build a list of people in the industry you respect and watch what they're interested in.
If everyone are using X, don't go with just Y because it is slightly more elegant or efficient.
- Relationships are key to your career. Align with good people and maintain those relationships.
- The product is more important than the code.
- Keep up with the latest tech, but don't necessarily use it.
- When starting a new job, learn the business first. Understanding what the product does and why is crucial and doesn't take long to learn.
- Avoid an adversarial relationship with other departments like marketing and accounting. Work together with them (back to point 1).
- Share your wisdom, don't hoard it.
- When you are no longer curious, something is wrong.
- Writing code is simply that. Enjoy it, don't glamorize it, and try not to obsess over it.
- Design for maintainability, not ability. Code should be simple, maybe even a bit boring, and not trying to be too many things. YAGNI and KISS. This gets rid of a ton of time wasting down the road.
- When faced with a standard problem, use standard solutions. Use popular proven languages, libraries and frameworks, instead of the hip new thing. This saves time which you can invest in the parts that are novel and require novel solutions.
- Understand the business value of the code you write, and the political process that produces its requirements. This knowledge will create opportunities to earn more, do more interesting work, and have happier users.
Learn a sense of... I want to say "taste", but it's more concrete than that. Learn what the bad ideas are, and why they're bad. Learn a sense of "that doesn't feel right" that's technical, not just aesthetic.
Learn what it's like to maintain a two-decade-old code base of a million lines or more. See what the problems are. Think about what you're doing when writing new code that's going to create some of those problems.
Learn to document what you're doing to an appropriate level of detail. Take the time to do so.
- Use tools and programming language that you personally enjoy, not the one trending on tech sites like Hacker News
- Focus on mastering at least one programming language
Those things are important, but I focused on them too much. I should have spent some of that time on higher level math-y skills like machine learning, numerical optimization, vision, NP hard approximation algorithms, computational geometry, control theory, etc.
Get exposure to customers. Try to get involved with decisions involving them. Many companies actively discourage engineers from having customer contact; this is bad, IMHO.
Get exposure to the financial side of whatever industry you're in. You don't need to do official work, but definitely make sure you understand how your company makes money and what its risks are. (Do a start-up or two; this will give you a visceral feel for what money is worth assuming the places you work at are run well).
Read a paper a week (e.g., something from usenix or the ACM, or whereever). Sites like The Morning Paper (https://blog.acolyer.org/) are pretty good; the thing is not to get caught in a rut.
If you're doing IT work, get involved in dev work. If you're doing dev work, get involved in IT. These feed pretty heavily off of each other and operational background will boost your engineering skills as much as coding skills will help your IT work.
Things I wish I'd studied harder, earlier: Statistics, practical aspects of databases and SQL, at-scale networking [didn't exist when I was a sprout], practical aspects of operating systems implementation (the stuff they didn't teach you in your course at school), maybe the first six months of an EE course . . . I could go on for quite a while. The good news is that there's no way you'll run out of stuff to learn, not in your entire career, and it's all (usually) applicable at some point.
Learn algorithms and Big-O just enough to pass job interviews, deeper understanding of these is nearly useless in practice, at least outside few narrow niches.
Learn to design and code safe and efficient multithreaded software. While not often asked on interviews, you’ll do that over and over again regardless on languages and platforms, because nearly all modern CPUs are multi-core.
Learn to use other people’s libraries and third-party tools. While their quality vary, good ones can save you tremendous amount of time. BTW, an IDE is one of these tools. Just don’t forget about costs (some might be too expensive for particular project) and licensing (some are GPL).
Don’t afraid to change jobs. Just that you’re working with nice people is not a good reason to stick to your employer. Make sure you learn new stuff, skills degrade over time as the industry moves to new technologies and platforms.
To this day, I still get very annoyed when someone takes what I have done, completely reworks it or even throws it away, doing something else that IMO is more complex and difficult to work with. My values have shifted from doing the quick and custom style to moving more toward standards and TDD in a style that everyone can pickup easily and understand.
This has made my work so much more productive in getting to the final production quality by a factor of not less than 2. In my youth, I spent 99% of my time fixing code as it broke. Now, I unit test and in many cases, end-to-end test with TDD frameworks providing myself with a much higher probability of success when pushing to production.
You actually have to play politics to be allowed to do your job to the full extent of your abilities.
That said, I think the best advice I can suggest is Divide et impera, https://en.wikipedia.org/wiki/Divide_and_conquer_algorithm
During my career I've spent a lot of time resisting and rejecting the overhead of time spent reporting what I'm working on and to some degree careful planning for the future. Like a lot of programmers, it only takes one or two short meetings a week before I feel like it's too much and meetings are a massive waste of time.
My first real job coding CG effects at DreamWorks, I got a black mark in my personnel file in my first 6 months for complaining about being asked to show my progress once or twice a day. It was during a 3-4 week coding project, and it took about and hour to prepare for dailies, so it seemed to me like I was being asked to sacrifice 25% of my productivity, to the detriment of both me and the company.
A few years later I'd been working on a shot for a month, thought it was exactly what they had described, and pretty good and close to done. But it kept not being finaled. Three months later when the director approved it, I looked back at what I thought was near done month 1, and it was crap. I realized that we sit in meetings and describe in articulate detail what we want to achieve for hours, everyone agrees vigorously, and people still walk out of the room having completely different ideas. I realized I need the overhead for course corrections for what I'm doing -- I will veer too far away from what others want without fairly continuous feedback. After seeing that in myself, I see it everywhere with others, programmers working too long by themselves will make what they want and not what the team needs.
Communication is what I want to improve. Not more of it, but how can we make it better?
I also wish I'd gotten out of C++ and into web earlier. ;)
A high-level design document of any significant system and subsystem is worth its weight in gold (or: programmer hourly rate * time to get up to speed on system).
This documentation will also help you in a years time when you need to either maintain that system, or need to remember how you built it so you can build something that is 90% similar to it for another project.
Take care of yourself. You are not a robot. Showering, skin care, hair care and sleep are important. It's worth it to go to a good stylist regularly. If you're happy, you're doing better work, and most importantly you're more approachable to your coworkers.
Don't ignore mental illness. It needs to be dealt with aggressively, on multiple fronts, until you've figured out the right ways to cope and be functional.
You can't just code alone in a corner. You need to socialize with your team, or you'll miss out on the meta knowledge (patterns, styling) that's being passed around the team.
You are smart. Give it a few years, and those impossibly talented and brilliant senior programmers will be your peers.
Don't be afraid to refactor and change code. The person who wrote it didn't know what you do now, because business requirements are constantly changing. Be aggressive - sticking TODO statements in code isn't going to fix technical debt.
Be delivery-oriented and don't be afraid to make design mistakes - it won't be perfect on the first time anyway.
Know more than your niche, get out of your comfort zone once in a while.
Respect your co-workers - even if they make mistakes, it's OK, you will too at some point.
2) Most companies have zero loyalty to you. They will fire you and thousands of others the minute they are in trouble, and without hesitation. If you're loyal to a company it's a one-sided relationship. Take care of yourself, the company will be fine without you.
3) Age discrimination exists, and it is VERY harsh. And your brain will eventually slow down while technology ruthlessly and quickly marches on. You might find it tough to keep up due to either or both of those factors. Save up early. Be able to retire by 45. Keep working if you still love it.
EDIT 4) Get EVERYTHING in writing. Happened in a conversation? Follow up with a simple email "Just so there are no misunderstandings, I wanted to confirm that..."
I also wish I had known to buy some Bitcoin.
Otherwise you will get calls during your vacation; you may not be able to work on other projects, switch teams or even get promoted - or if you do, you will still be supporting the code you wrote years ago on the side.
It took me a long time to get this bored of it though, so if you are similar you should be OK for a long time maybe.
If you get paid well, don't spend to match your income. Save as much as you can. You never know if you'll lose the drive 10 years in.
I know the world of code can be very exciting, but after a lot of work you start to see there is nothing new under the sun and you fix and write the same old things in different forms. And most of the problems you grapple with are man-made, like the idiocy of using languages without static typing voluntarily
I think you already said it: "I'm also realizing there's SO much more to learn."
Don't stop learning. It was probably around 1988 when someone suggested I look into Lisp and I dismissed the comment at the time, although I did look into AI. I do wish I had known more about Lisp, not necessarily programming in Lisp, but just the knowledge of the concepts that come out of learning Lisp: garbage collection, stacks, lists, trees, macros (not the terrible C macros I was using at the time but Lisp macros), parsing, code generation, profiling, the benefit of programming in a more functional way, and I am probably missing a lot of things here I take for granted. Don't stop learning.
But the power of Lisp (Common Lisp, in particular) goes far beyond all those.
2) Get solid on the basics and stay current: data structures, algorithms, computation and basic operating systems. Without these you'll never reach high levels of competency.
3) Develop boundaries. I've seen stellar developers reduced to a pile of depression and anxiety by poorly trained managers getting them to overcommit. Learn to know what you know well and what you do not know well. Push the rest back onto your manager and make them do their job.
4) Take time to enjoy and savor this time. We're in an age of technology that has never before existed.
The more you know the more you will come to understand you don't know much; that is both good and bad (Dunning Kruger vs Imposter Syndrome).
Every time you think you are the best in the room, look around and ask yourself are you overestimating your knowledge. If you are still the best in the room, maybe it is time to find a room with smarter people.
Not every solution requires code / technology.
The best code is easy to read and even easier to delete.
Give your code to the most junior member of your team - if they struggle with it you need to make it simpler.
There are many many lessons like these around - the single most important one - always be open to new ideas no matter how much they oppose your current beliefs; strong opinions, weakly held.
Also, it's completely open-source.
This also applies to how much energy you put into your work. I started out trying to meet crazy timelines and for the most part I did it. But eventually it became the norm and I couldn't keep up. It took a lot longer to get managers to understand that nights and weekends are not sustainable.
Lastly I would have jumped ship sooner. I've been working for the same company for 11 years and now that I'm in the market for a new job, no matter how much I tried to diversify myself within the company, I don't always have specific skill sets these new positions are looking for.
- "how to solve it" by george poyla
- asking more "why"s to problems
Explicit is better than implicit. All state is hard to reason about and debug. Code that doesn't have tests is brittle. Short code is better than long code and no code is better than both. Inheritance of implementation is hard to reason about.
Some technical advice:
Write comments about why you're doing something, not how. Write lots of comments. Check preconditions, especially nulls. Write explicit error messages for every failure: you'll be searching for them one day.
One non-technical thing:
Understanding the problem you're trying to solve is often better than any technical knowledge. Understand the business processes, the users and the people and you'll find you're vastly more effective.
Whenever you feel like writing a comment explaining why you're doing something, step back and consider if you can refactor the code so that it becomes self documenting. Code and comments get out of sync easily.
Instead of checking for preconditions, step back and consider if you can make the illegal states unrepresentable. If you have a decent type system available (sum types, no nulls), that's often straightforward.
The best peice of code, the best test and the best comment is the one you didn't have to write because of good design.
If you start going down a path that makes you feel less happy, take a moment to ask yourself why that is, and what you're getting from that tradeoff. If you can't answer that question in a way that makes your inner mind happy then figure out a way to change course. And a slightly higher salary is not a good reason.
It is important to meet the right people that one can learn from (who are ready and able to share their knowledge).
Spending too much on sites like HN/slashdot/reddit is a bad idea. Again one has to find the right balance (and the right sources of information that do not turn into time sinks), balance is important like with the other stuff ...
When this happens repeatedly over time in an organization you wind up with a large, complex codebase that tends to solve problems in pieces and at scales other than the correct level (i.e. as the user experiences it).
Usually, the best approach to solving the largest portion of the problem at hand does not involve writing code, and if it does, it won't be code you are interested in. Such is life as a programmer.
Your company will try to stab you in the back one day, so you have to keep an eye open for it. Always reserve 1% of your career energy towards looking for a new job greater than or equal to your current job. Whenever you find one, take it, and just keep on looking. (If you do contracting, never let any single client represent more than 50% of your total income.)
It's harder for them to hit a moving target. And even if they do get you, they're more likely to just wing you instead of hitting something vital.
Most people are not that good, or confident, even among higher earners.
Most programmers are short-sighted, selfish, and lazy, so it's unusual to find yourself with a group earnest talented people who have experience. Appreciate it, and take advantage of it while you can.
Take your testing as seriously as your development. Not just in the details of the implementation, but understand your user and your use cases. Write end-to-end test suites, integration tests, and unit test complex logic.
Don't be one of those "unit testing is enough" or "I TDD all my code." I find the more time people spend on little testing, the bigger problems seem to fly through to prod.
I wasted years trying to do things "properly" (completely pure OO in my case) when I could've been releasing software, and wasting effort anguishing over why I thought differently to the gurus.
Now I have no time for programming fads. But try not to go too far this way - it's easy to be too late an adopter too.
The next sentence should be: So don't fucking do that. You do your family, your employer, your coworkers, and most importantly yourself no favors by working 60 hours a week in front of a screen. It doesn't matter if you're working for yourself or someone else.
If you think otherwise, you've been brainwashed.
- If you do something more than once, automate it. Create a script, write a bash alias, something
- Keep reading; Go to conferences; Get a subscription to O'Reilly Safari - worth every penny; It's easy to become a dinosaur as a programmer
- Step through every line in your code - TDD is a good way to do this (corollary: figure out a good TDD methodology for your workflow).
Good luck!
Anger is best solved by not ruminating about it---the catharsis hypothesis is busted.
Read other people's source code of interest, closely.
Increase focus/limit distraction by limiting the work-in-process with Kanban-like systems.
Assembly language matters but abstractions can multiply the power of your systems. Conversely, too many layers of abstraction is a design-smell.
And soft-skills care not what programming language you speak.
Independently of work, learn a new language once a year.
On this and other forums it seems like everyone knows everything, but that's only because there's a lot of people here.
If you're going to use design patterns, great. But don't argue about the exact official gang of four definition of the facade pattern - a more productive conversation is about which specific bits of the pattern help you solve your problem and which are an impediment.
Tests great, but when you're just starting a brand new project where the behavior and spec is changing as you build and learn, should you suffer through brittle unit tests because "not testing is bad practice", or could you perhaps start only with integration tests, and wait a little bit until you start doing anything more granular?
Complex git branching / release / hotfix / etc schemes can be great in a larger organization, but when you're on your own, do you really need all of it or is it too much overhead? If you don't have a staging environment, should you have a staging branch?
Summary: a) Am I actually trying to solve a problem? What problem am I trying to solve? b) Is this thing going to solve my problem or a problem that I don't have? c) What can I change so it /does/ solve my problem?
2) In a large enough codebase, there is always bits that are shitty for a variety of reasons involving bad programmers, bad practices, no practices, bad requirements, terrible deadlines, old tech, whatever. You don't /want it/ to happen, but it will. Or perhaps you'll be dropped into that codebase, and so you'll have had no say to begin with. An unappreciated part of the practice of software architecture is about containing current and future shittiness, stopping it from spreading, managing the risk around that, not allowing that to impede current development, setting up a surrounding architecture, getting people on board socially to do the right thing, having a good plan to replace it and acting on that. "No new code until everything is clean and tested" sounds so valiant, but I'd like to see it happen in a 100 person organization with bills to pay. Alternatively, after you've contained things, then you can feel free to adopt such policies at a smaller scale within well-defined regions of the code.
And IMHO, design patterns make the constipation worse.
- If a language's syntax is written using an structure that the language itself can easily manipulate, - in such a way that the source code can generate new source code, using the full power of the language (no restrictions), - in a easy-to-program, straightforward way,
... then you practically have a Lisp language.
As somebody important said: "Lisp is the programmable programming language". This is the key difference among the rest of the languages.
I have spent about 26 years programming and only this year I set myself to grok Common Lisp. The power of Common Lisp, and in particular its object system (CLOS) makes languages like Java seem like ugly toys for miserable people.
I don't doubt lisp is fun and easy to write, but power doesn't have much say when it comes to refactoring. That's where convention wins out. How is refactoring 10k lines of lisp?
Lisp compilers provide diagnostics about code; it's just those diagnostics aren't the arbiter of whether or not something gets to execute.
Continuous integration first - first line of code second.
Understanding that writing code is a small percentage of my day - then there is testing, designing, writing docs, deploying, automating, infrastructure configuring, discussing with stakeholders,
Learning multiple languages - especially from different families (procedural, functional, scripting, low level, etc).
Had I known this sooner it would've sped me along considerably towards finding a lot of cool things that give me more motivation to program.
I would add that you shouldn't be afraid to use new tools is they get you to the end faster. Common case for me: I use c# for almost everything, but nodejs wrapped in an API for crawling
Looking back 24 years, I'd also add, to be more involved in the local hacking community and participate in hackathons.
Anybody can code, but to make a difference, you need to network ;)
Throughout my career, programming mentors have shaped me to be who I am. I've learned most of best practices through code reviews and from my mentors.
If I knew these exercises before the operation, I could have prevented it. Leading a healthy life, proper posture when sitting, physical exercise (for spine - especially swimming) are extremely important in the long run. Your spine degrades with time, load and improper posture. Sitting in general is unhealthy. Humans didn't evolve for sitting. I'm more comfortable lying or walking. People ask me to sit trying to be polite, but it really makes me less comfortable.
Since we read code more often than we write it, put a little extra effort into making your code easier to understand.
It tends to be pretty easy to speed up readable+simple code when you need to do so, but fixing broken fast+clever code is much more difficult.
I got into web development in the last 2000's doing PHP backend development and CMS work, and now everyone seems to have gotten into more opinionated dev environments that really involve anything but PHP.
I wish I designed a testing strategy for the feature I am developing.
I wish I learnt and embraced good engineering practices and spread those in the organization.
You will thank me.
Your skills will grow, but the churn of tools and techniques will have you relearning things on a regular basis.
It's not them, it's you. Any problem you have is your problem and the solution is something you're going to have to do. Be it a compiler bug, deadlines blown through by partying interns, shoddy code written by contractors, insane deadlines imposed by self righteous VPs, etc. All of these problems are caused by you. You took these jobs. You fed the mice cookies. You didn't say no. You didn't spruce up your resume and blog on LinkedIn. You are the only person that is ever going to try to help yourself, so if you don't like what's going on, there is no where to look but inwards.
Every line of code is a devil, waiting to bait you. Every curious syntax, handy shortcut, convenient convention that only you and the few who read the docs will know about, is bait in a trap. It's better to write less code, simpler code, and code that eschews advanced features in favor of being obvious. Imagine yourself having not slept for 24hrs, being drunk, with a CRT monitor at 640x480, typing on a keyboard covered in elmer's gluge, and then write code you could debug that way.
In about 20yrs on the job I don't think I've ever seen a situation that truly called for more performance. I've seen bad processes that were too slow because they were bad, and I've seen inner loops that needed to be unrolled, and I've seen (written) code that was hitting the database in ways that were totally bonkers. Slowness is mostly about bad decisions earlier up in the decision tree. Unless you're writing trading algorithms or video games, you likely have no use for your program to run any faster.
Prefer bad working code over good code that still isn't producing any useful output.
Your choice and relationship with your spouse will have more of an impact on your career and long term happiness than anything in technology. Take care of home first. Then go to work.
You are going to need a few key side skills: public speaking, making small talk at parties, presenting to people above your pay grade, technical writing, etc. These are key differentiators that are more valuable than being able to write more or better code.
When you're feeling burned out, take a day or two off. If you aren't able to, or you do and it still doesn't help, then something deeper is wrong.
Cutting down on the drama of deploying and maintaining production software is just as important, maybe more, than fun during development. Yeah some languages are excrutiating to code in, but they run smooth, and that's worth a lot. And some languages are a lot of fun in the editor but a bitch on the server, avoid those.
Steal ruthlessly. Anybody who is doing anything cooler or better or faster than you, buy them lunch and ask them what they're up to. You don't have to follow in their footsteps, necessarily. But at least being familiar with other ways of accomplishing things really helps broaden your horizons when brainstorming or thinking about problems.
It's okay to take long breaks to do something else. You can always come back.
Make friends and stay connected. Your rolodex is your escape hatch if things get ugly.
You are a business. The product is yourself. You're the founder, CEO, president, etc. When you answer the phone, do so as the CEO of You, Inc. Ask yourself: if I was a business person, and one of my employees was representing my business to my customers the way I am doing now, would I fire that person, or promote them?
Knowing which rules are actually enforced and which rules are just for keeping chumps corralled can really help your navigate a bureaucracy.
Making friends with people who make and enforce rules can get you out of following a lot of those rules, or just provide back doors into the processes.
You pick your boss and at work that is likely one of the most important decisions you'll make. If you don't like them, find a new one.
Apart from startups: in startup, technical bullshit is replaced with business bullshit.
Still not a superstar, but my code became better in the last 4 years.
- get a mentor. Some chilled senior guy with lots of experience. Speak to him regularly to fish for knowledge. But don't get hung up on everything s/he says. Programming is huge field with lots of parts.
others:
- there is no silver bullet
- simple is not easy (search Simple Made Easy by Rich Hickey)
- always be pragmatic
- there are indeed better approaches than OOP, which differ greatly in long run of project, and pay back (FP) later, and it matters
- avoid "the chase" of latest best-good thing, get productive in something that matures well
- don't ignore latest practices and latest progress just because of the above mentioned things. Keep learning and try to reapply new stuff (at least in your head) to range of problems you solved, and think if pro-s and con-s.
- avoid any heated discussions about languages
- keep your ego out of work
- the less you need to code, the better. You are paid to solve problems, not to churn code.
- finished is better than perfect. Don't gold plate your solution. On flip side, don't code shit and try to excuse it with above-mentioned sentence. Be pragmatic.
- types are your friends (and friends of your colleagues that have to work with your code), take time to learn how to leverage them
- unless you're working on life critical software, don't stress (even then don't, but...). If you feel pressure and stress, work on handling that. There is no point in being miserable because someone needs ability to put dog face onto a photo.
- you'll be programming for a lot more years to come. You may genuinely like and enjoy it throughout that period, or hate it. If you hate it, it doesn't mean you're not suited for programming, maybe you're not using language that suits you or allows you to express yourself clearly. Yes, people say languages don't matter. From your perspective as programmer, they do (they don't for business as long as it gets job done etc.).
- learn new language at least once per 1-2 years. No need to use it, just get familiar with it, it's design choices, it's public APIs, some internals. Language creators are generally very smart and you can learn from them a lot.
- Once you're a bit more senior learn from other (junior) devs. They're the ones usually chasing latest hot frameworks. They have time for that. Be appreciative about that, and take your time to listen to what they have to say, and what excites them, and how it relates to your experiences. It is also opportunity to grow.
- Try to contribute to open source projects. Not to build portfolio, github or whatever. But to give back some of the service. You'll be paid back by learning a lot.
You don't get to complain if you are part of the problem.
- Selling skills either by sharing knowledge in form of code or teaching/blog posts.
- Learning the fundamentals.
no point knowing how to code a web server in 6502 assembler if it hurts every time to sit in front of a computer.
The important thing is to remember that strain creeps up on you slowly, then hits hard. You can get away with bad habits for years, but left unchecked one day you'll find you can't do anything, it all hurts too much.
Don't push yourself. If you find yourself aching a little, address the problem rather than pushing through it. I know several people that were knocked out of commission for the better part of a year after a few decades of casual neglect.
2. Pick a programming language and/or ecosystem and stick to it. That's not to say there isn't power in being a polyglot, but in order to get really good you need to pick one thing and practice it. It's that simple. That said, do not brand yourself as any one thing or be too specific. The key is to both specialize and generalize. You need to be malleable enough as things change, but at the same time not constantly chasing your tail with the latest thing. This fine balance comes with experience, as most new technologies and techniques you will find are the result of someone rediscovering something. I can't count the number of times I've seen something rebranded as new or revolutionary that was originally published as a paper in the 50's or 60's.
3. Own what you do. Don't wait for others to come to you with problems, think about ways in which you should be improving your software via instrumentation and closed loop controls. Try to understand the users of your software and what they really want and need. Sometimes little things and details that are seemingly unimportant are very important indeed. Software is a way for you to directly influence and collect information about the world, so you can be constantly testing your assumptions and refining your model.
4. Do personal projects. It's the only way to avoid burn-out and to keep yourself interested. And in many cases, personal projects can shine the light for you on where to go next or what to do next.
5. Get good at interviewing others on a team and make yourself part of the interview process. Real team building is a far more valuable skill in accomplishing your goals as an engineer than becoming a manager.
6. Stay close to the tech. At a certain point you may find yourself in a position where you aren't coding or creating every day. Avoid this at all costs. It doesn't matter if you have a team, or if you're in an architect role, or whatever, you should have the code checked out at all times on your computer, have it working, and be able to contribute at a moment's notice. If at any time any of this isn't true for you, stop what you're doing right now and make it true.
7. Don't be afraid to throw out huge legacy code bases and start over from scratch. Nature does this all the time; it's called trial by fire. The second time you do something is always easier than the first and you can really eliminate a lot of debt for you and your team.
8. The first time you do something, if its not messy and weird you aren't trying hard enough or pushing yourself hard enough. The code will be awful. Don't strive for perfection in the code the first time, if it sticks you and others will have plenty of time to refactor and make it better later. I've seen tons of "perfect", unused code that has never seen the light of day again and its really sad.
9. Work for a variety of companies, small and large, startups, mid-size, big tech, and do freelance at various parts of your career. Different size companies have different goals, needs and problems and it will help you understand what is applicable to a Google does not matter at all to a startup or mid-size company.
10. Work for companies that are actually doing something, preferably new work, and try to match that to your interests at the time. Avoid places and people that are toxic and do not have a deep love of technology and do not identify as "nerd"/"hacker"/"geek" etc (unless you yourself do not identify this way..)
Early on I was always tempted to prove how smart I was by writing very neat code that nobody could understand because I was using some esoteric library or a weird pattern that only kind of fit (although it worked). Don't do that. Try to be very VERY obvious and you'll thank yourself later.
Its easy to over-engineer any project, but I find OOP especially easy to screw up with outsmarting yourself. You've heard of "spaghetti code"? Well with OOP the dreaded paradigm is 'ravioli code' which is tiny little classes all over the fcking place.
Find a better way.
Another rule of thumb someone told me once is that your classes should not be longer than about 1 page of text. Now, before I get yelled at, yes, its very subjective. You could have 100 lines on one page and I could have 30, I get it. But I think the idea is at least it is some* point of reference so you yourself can judge if a class is trying doing too much.
I worked with an "Architecture Astronaut" (see: https://www.joelonsoftware.com/2001/04/21/dont-let-architect...) one time who was supposed to be giving me a way to access a flag in the database. Just a simple boolean that let me set something to, obviously, true or false.
This guy checked in a 200 line class and walked down to my office to teach me how to use it. Finally I said "can I just set the value manually?" "Sure" he says, "Just use this function" and he showed me a 3 line function buried in there somewhere. Last I heard he is still confusing everyone with his overly complex solutions to simple problems for Ford.
Programing is FUN, but it's also a profession. Don't get too lost in the fun of the moment. Write clean, obvious code and you'll see that you don't have to make things complex to have fun. You'll have more fun solving those big problems now because you made everything nice and neat and clean along the way.
I'll end on a quote from Blaise Pascal, Winston Churchill or Mark Twain (depending on how you google it) that I think applies here as well:
"If I had more time I would have written you a short letter, instead I have written you a long one."
This could be rewritten like this:
"If I had more time I would have refactored you a short class, instead I have coded you a long one"
Its a comment about editing (obviously). yes, write long classes then delete all you can to make them simple like I have explained above.
:)
I should make this comment short, but I do not have the time.
You can go even deeper and get into deep VIM style skills but there are many very easy things to learn that let you do stuff so much faster. Whatever editor your use, learn to use it.
EDIT: thanks for the advice guys, I use Jet Brains range of IDE's for school cause free licensing and I'm using VS for my summer internship. I'll look into emacs though, thanks for the suggestion!
The TL;DR: dive head first into some editor and try to immerse yourself in the thinking of the editor.
and here: https://jackmott.github.io/programming/tools/editor/ide/visu...
I'm not familiar with jetbrains but if you can probably find equivalents for all those VS tips in jetbrains.
are you one of my interns? haha.
It can be worthwhile to at least partially master emacs/vim as well, since these exist on all platforms, can be very powerful, can use them when remoted into a tiny linux cloud box via a terminal, etc etc.
Also some aspect of your job will always suck. Even if you find the perfect job the manager can change or even company gets taken over. For control you need to run your own biz.
2. Try to setup a nice workflow in the early stages. To me, this includes setting up the code in git, and a minimal test/deploy system. This encourages me to commit often, make incremental changes, and rollback/switch branches frequently.