Ask HN: For those programming 10+ years, what do you wish you knew 4 years in?
I've been programming for ~3 years now, first just on the side and now full-time. My learning has been in stops and starts. Now I can feel the cumulative learning paying off. I'm also realizing there's SO much more to learn. What advice do you have for programmers just hitting their stride?
537 comments
[ 2.2 ms ] story [ 358 ms ] threadAnd 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.
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.
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.
Also, it's completely open-source.
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!
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.
- 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.
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.
- 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.
If everyone are using X, don't go with just Y because it is slightly more elegant or efficient.
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.
https://xkcd.com/1205/
On the other hand, sometimes you're automating for reasons other than time savings. Maybe reproducibility or auditability.
[1] https://andrewstahlman.com/posts/IsItWorthTheTime.html
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”
* 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:
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#
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.
That said, I think the best advice I can suggest is Divide et impera, https://en.wikipedia.org/wiki/Divide_and_conquer_algorithm
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.
Most people are not that good, or confident, even among higher earners.