top | item 18000410

Ask HN: What topics/subjects are worth learning for a new software engineer?

253 points| jmeiha | 7 years ago

I'm trying to cultivate my ability to identify worthwhile topics to invest time in learning since I have only recently graduated from university, so for the most part have been sticking to the yellow brick road laid out for me thus far.

What would some of you guys think about learning if you were just starting out in the industry? Or even better, what does your process for orienting yourself and making these kind of decisions look like?

Any and all advice would be greatly appreciated.

141 comments

order
[+] baron816|7 years ago|reply
Too many software engineers get into a mindset of “just make it work.” For me, making it work is only half the battle. You need to build something that will make it possible for you or someone else to come back to later and be able to reason about and modify or extend.

I interview a lot of job candidates and I give them a very simple problem. Pretty much everyone can solve it, but I’m not just looking for them to solve it. I’m looking for them to find the right abstraction—one that will make it easy to extend the problem and for junior devs to look at the solution function and understand exactly what it’s doing. Almost no one passes.

My coworkers ask “just make it work” problems in interviews, and I believe that has contributed to our codebase being a nightmare to work with.

I think most software engineering is an organization problem, rather than a optimization problem. My advice: learn functional programming and object oriented design. You will learn how to write declarative code that is loosely coupled and not dependent on its context.

[+] mooreds|7 years ago|reply
> Too many software engineers get into a mindset of “just make it work.” For me, making it work is only half the battle.

I had a conversation with a mentor talking about hiring. He said that he typically saw two types of engineers:

Those who can start something.

And.

Those who can finish something.

The former can tackle problems that seem to have no solution, start from scratch and build something that just works. They are energized by greenfield development and close consultation with customers/users.

The latter can work within larger organizations, know about idiom for the technologies used, think about the right level of abstraction, and provide polish for the codebase.

Teams typically need both kinds of engineers.

I found out what kind of engineer I am years ago. That's led to roles that make me happy.

Agree that fp and oop are good investments.

[+] scarface74|7 years ago|reply
Too many software engineers get into a mindset of “just make it work.” For me, making it work is only half the battle. You need to build something that will make it possible for you or someone else to come back to later and be able to reason about and modify or extend.

There are no absolutes. In small companies that are just trying to get that one whale or feature that can keep them in business and prove to thier investors that they have achieved “product market fit”, sometimes just duck taping together makes sense. Other times companies aren’t looking for a long term product, just something good enough so the investors can have an exit strategy.

Yes I have worked and been a Dev team lead in both the above environment and one that wanted well tested, well architected software that they wanted for the long term and had the resources to see it through. You have to know what the end game of the business is.

Look at Twitter. All indications was that early on that their code base was horrible. They proved their was market, got the money and rearchicted thier system.

[+] pfarnsworth|7 years ago|reply
> I’m looking for them to find the right abstraction—one that will make it easy to extend the problem and for junior devs to look at the solution function and understand exactly what it’s doing. Almost no one passes.

If no one passes, it means you are instead asking them to recreate what YOU would do, and basically asking them to be a mind reader. A good interviewer would know that there is more than 1 solution to everything, and that there are equal, but completely different solutions to the same problem. Someone could abstract the problem completely different from yours, but still be correct.

[+] dudul|7 years ago|reply
> I’m looking for them to find the right abstraction

Nothing worse than an interviewer asking a design/coding question and who already "knows" which answer he/she wants.

[+] ganashaw|7 years ago|reply
Would you mind sharing that problem? Always looking to improve my own interview questions.
[+] yourbandsucks|7 years ago|reply
>> Pretty much everyone can solve it, but I’m not just looking for them to solve it. ... Almost no one passes.

Sounds like a not-great process IMO. You're expecting them to understand a lot of what makes you tick and what you personally consider 'maintainable' based on a 1 minute problem description.

My opinions on what makes code maintainable have evolved and fluctuated (based on most irritating current problem) significantly over time.

[+] graycat|7 years ago|reply
IMHO, do all you want on (A) "declarative code" and (B) "find the right abstraction—one that will make it easy to extend the problem" and I will applaud. Indeed, as I entered grad school in applied math and had a good career going in software, two profs getting ready to teach a computing course asked what advice I would give. I responded with something like your (B).

Also for (A), at times I tried to write code that would have some algebraic properties: E.g., as I was writing various sorting routines, routines to invert a permutation, to apply a permutation to an array, working with the fast Fourier transform, there were, of course for these topics, some cases where could regard calling one of the routines as something like an operator in parts of math/physics, get new operators by composing the other operators, and, then, saying when some of the operators were equal to some of the others,, net, nothing, or invert another one. I got some such before I got back to just get it done.

But at this point, IMHO, for all can do on (A), (B), etc., my view is that the crucial part is missing: I urge to do all you can on (A), (B), etc. and then just take the attitude that the code doesn't mean anything at all, is just gibberish, and then get the important meaning by documentation in a natural language, e.g., English.

E.g., in a physics text

F = ma

has with it one or more whole chapters of well written natural language explaining what the heck that equation and its symbols mean. We do not leave the math by itself as self-documenting, self-evident, clear, or any such thing.

Then, write the documentation so well that, if had to select and keep just one of the code and the documentation, then definitely leap to keep the documentation: If the documentation is good, then can reconstruct the code fairly easily. Without the documentation, understanding the code well enough to reconstruct the documentation tends to be a really big puzzle problem and likely in principle impossible.

Bluntly, knowledge and meaning are communicated in natural language. E.g., well written pure math is in complete sentences.

[+] holografix|7 years ago|reply
I’d also like to know that question if you don’t mind. I’m considering a career change to development full time.
[+] yashap|7 years ago|reply
Take on challenging problems, ask lots of questions. Always try to understand both the technical decisions and business decisions/value in whatever project you’re a part of.

Try to avoid anything resembling blog/resume driven development - the real things to worry about are writing code that solves the business problem in a simple, quick way, while being easy to modify in the future, low on bugs, easy to monitor, and ideally reasonably performant. Using hot new frameworks/tech is unimportant, but writing well tested, modular code with the right data models, simple architecture, and good logging/telemetry/alerts is very important.

Get comfortable with a set of tools that make sense for the work you’re doing - an editor/IDE, a debugger, a shell (and common Unix programs, if you’re in a Unix environment), a VCS, whatever build/deploy tooling your company uses, etc.

Avoid the common dev mindset that dev managers, product managers and/or designers are the enemy. It IS your role to focus on important technical needs, but realize that they must be balanced against delivery times and business value. Sometimes you need to leave hacks in place, if there’s not too much cost to leaving them there. New features and bug fixes ARE often more important than cleaning up code/architecture, when you do take time for technical priorities, make sure you’re choosing high impact ones.

[+] Aeolun|7 years ago|reply
I think you are needlessly dismissing resume driven development.

While I agree that it is no good from a technical perspective, it’s really a fairly big part of what companies look at when they hire you (as I learned).

Make sure it contains at least the latest fancy technologies in a professional context, and it will really help with your desirability.

Then after you join the company, you can try improving their code to be up to standards.

[+] auslegung|7 years ago|reply
I was recently given this list of books by some very skilled engineers who I trust

1. [The Pragmatic Programmer](https://pragprog.com) 2. Martin Fowler's [Refactoring Book](https://martinfowler.com/books/refactoring.html) 3. Kent Beck's [Test Driven Development: By Example](https://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/...) 4. [Thinking in Systems: A Primer](https://www.amazon.com/Thinking-Systems-Donella-H-Meadows/dp...) 5. [Zen Mind, Beginner's Mind: Informal Talks on Zen Meditation and Practice](https://www.amazon.com/Zen-Mind-Beginners-Informal-Meditatio...) 6. [Pragmatic Thinking and Learning: Refactor Your Wetware](https://www.amazon.com/Pragmatic-Thinking-Learning-Refactor....)

[+] icc97|7 years ago|reply
My personal opinion but this is purely because I enjoy it the most is functional programming. So much of the positive changes I've seen of late come through functional programming.

For example:

* ReasonML - this is what the founder of React is working on now. The ReasonML claims itself to be JavaScript 2030 (I see it as JavaScript + TypeScript + Immutable.JS + Redux). This contains a lot of the concepts from JavaScript so is a reasonable step to make

* If ReasonML isn't too scary it leads you down a path to OCaml, F# and Elm

* Rust (not strictly a functional programming language, but is ridiculously fast and contains well implemented Linear Types that makes Haskell's Simon Peyton-Jones jealous [0]) - this is one of the most loved programming languages according to the Stack Overflow survey

[0]: https://www.youtube.com/watch?v=t0mhvd3-60Y

[+] analog31|7 years ago|reply
Don't get too busy. This is easier said than done.

I've noticed that when we hire newly graduated engineers, we saturate them with CAD (or its equivalent in programming), bureaucracy, and troubleshooting. They forget the cool stuff that they learned in college, such as math and theory, and burn out.

If you want to keep up with that stuff, you have to figure out how to weave it into your regular work, so you have an excuse to continue learning more about it, or give yourself some free time to learn cool things that you might use later, or might not.

A lot of people tend to measure themselves by how busy they are. I believe that's a death trap.

[+] OliverJones|7 years ago|reply
I've been at this for a long time. I've had to learn many new languages, toolchains, and stacks over the years. I try to read at least one technical book a month. So will you. That's a fact.

Understanding systems (no, not operating systems, not file systems, not that stuff) will give you the ability to create really good stuff. By "systems" I mean, basically, human systems. For example, understanding why the New York City subways are working poorly these days involves knowing something about politics, economics, electronics (the signaling systems) and demographics.

Knowing why software companies sometimes have a hard time "putting themselves out of business" involves technical debt, new technology, resistance from people who know how to succed and want to keep doing it.

Why doesn't the Roman Catholic Church let their clergy marry? That's the mother of all systems questions.

How to bust into this way of thinking? Read "The Fifth Discipline" by Peter Senge. Be an anthropologist. To practice, read worseThanFailure.com as am amateur anthropologist. Don't just laugh, try to figure out WHY people do silly-seeming things.

[+] __exit__|7 years ago|reply
When you mention technical books, do you have in mind books on programming languages/frameworks or more focused on general concepts/skills useful for the daily work?
[+] corysama|7 years ago|reply
Ask old engineers about their problems and they’ll tell you it isn’t tech. It’s all people. Getting people to understand, get motivated, relax, get over themselves. These are the issues that hold back progress in practice.

But, if you want tech, machine learning really is horribly interesting and useful right now. Ocaml and Erlang are good systems to learn from and carry over to other systems. CUDA is a rare and powerful skill. And, if you want to get serious, learn TLA+ or Coq.

[+] pulkitsh1234|7 years ago|reply
On a related note (sorry for hijacking)

Should you invest time in learning for interviews or your own personal growth once you are 2-3 years in the industry ?

I understand that both sets are not mutually exclusive, but where should you put your time on ?

Investing time specifically to give interviews: Leetcode, Cracking the Coding Interview, TopCoder, etc., may increase the chances of getting a better job then your current one (and will make you a better programmer too).

On the other hand reading books like 'the pragmatic programmer' and other classics, won't necessarily put you in a better position to get a better job (in most companies), but will surely make you perform better in the current one.

So, is it ok to put it this way:

* If you are happy with your job and you can see that you can stay 5+ years at the company (basically FAANG ?): Invest time in learning for personal growth (Design Patterns, Refactoring, etc)

* If you plan to switch / want a better salary / company sucks / <every_other_reason> : Invest time towards preparing for interviews specifically ?

[+] avocadoLife|7 years ago|reply
This is exactly my dilemma. I've been in the industry for 2 years but done very little personal development in my own time and my job has been quite limiting in pushing my skills in the direction that I desire.

I value my after work hours to pursue other things/exercise/have a life. This makes me put even more thinking into how should I be spending my already limited time.

Currently I'm sticking to doing some MOOCs related to my my development path (Android) and then I want to crack on a few personal projects. On the other hand, the clock is ticking and I really would love to prepare well for better career opportunities...

[+] amrx431|7 years ago|reply
This is the most apt and serious comment in the thread.
[+] skrebbel|7 years ago|reply
Learn to ship.

Make something useful, even if just for you and maybe three friends. Ship that. Sooner. Ship it when it hardly works. Then iterate.

This will teach you all the good bits of "agile", some requirements thinking, pragmatic programming, and (if it's a web thing) some basic "how to maintain an app on a server" skills, all in 1 go. It's also all stuff that is super hard to learn from books or from too-experienced coworkers.

[+] garysieling|7 years ago|reply
I found that blogging the steps as I do side projects made progress really helped with this - it makes it feel like I'm always completing something. It also allowed me to break a problem down into small steps (what be done in 30 minutes-1 hour before work).
[+] 3pt14159|7 years ago|reply
Understand that questions that anyone reading HN can answer are largely filled with answers and votes that are what the average HN commenter thinks. The average HN commenter makes an average wage.

Find people that sold businesses or make high six digit incomes and ask them.

That said, my two cents[0] is that you should run towards the hard stuff, not away from it. Seems hard? Seems ill-defined? Top dollar.

AI, Rust over C, Ember over JQuery, complex ETL jobs, OS programming, ASICs, FPGAs, space circuits, military gear, OS simulators, codebase analysis tools for red team, nano second computing for wall st, etc.

My only proviso is that you should probably stay away from learning about cryptographic algorithms unless you're also interested in learning about quantum computing. Crypto right now is pretty easy and cheap for the 99.999% of entities that need it; and unless you're really good you're probably not going to break modern algos without quantum and even if you do there are a very small number of actors that will pay for your genius. MITM attacks that involve breaking crytpo algos are mostly state actors and huge criminal gangs.

[0] I guess I've sold a company, but some people working at Google have made more than I did so I don't really feel like I fit the category of people you should be asking.

[+] 01100011|7 years ago|reply
> military gear

Maybe. I think there are lucrative opportunities in serving the military industrial complex but they are best exploited by insiders with experience and connections in that space. You need to know the lingo and need to know the right people. You also, probably, need clearance, which you can usually only get by being former military or formerly in the defense industry.

[+] vogre|7 years ago|reply
Learn SQL and you will be able to work with any data-related app. Learn HTML and you will be able to make an UI out of nowhere. Learn GIT and you will be able to share your work with others. Learn unix shell so you can deploy all that shit and conquer the world.
[+] chubot|7 years ago|reply
Yes it feels like SQL, HTML, and shell are ubiquitous and powerful technologies that most people think they know, but probably don't. Certainly I could have learned more about them in the first decade of my career. 15 years into it, this knowledge continue to pay dividends.

I like this contrarian advice: rather than chasing the latest new thing, learn SQL, HTML, and shell. They continue to exist because they do things well that Java, Python, and Go don't. I suspect that will still be true in 10 years, so it's a good thing for new engineers to invest in.

(Learning the foundations of git is good too, although the outer layers are arbitrary and nonsensical.)

[+] garysieling|7 years ago|reply
SQL is incredibly valuable, it also allows you to do a lot of analysis to triage tickets or to get business insights (how many users does this feature affect, etc)
[+] snarfy|7 years ago|reply
In most other professions from doctors to electricians, years of experience equates to years of expertise. In software development, the technologies change so rapidly that a large amount of time is spent learning the technologies and tools. You may be a veteran Java or C++ developer with intricate knowledge of the underlying frameworks and implementations. At some point those technologies are replaced and that knowledge is worthless. All those years of experience are gone. Sure some general experience was gained, but anything related to specific implementation details is gone.

The only thing that stays are the fundamentals. Focus on the core science and math aspects of software development, and your skills will only grow over the years, instead of constantly being deprecated as the landscape changes. Learn all of the design patterns and O notations and forget about the latest javascript framework flavor of the week.

[+] mayankkaizen|7 years ago|reply
What a valuable comment!

I am 37 and I am not a programmer but I do read a lot about programming and related areas. Practically speaking, I don't see myself becoming a professional programmer but I still want to pursue programming just to whet my learning appetite.

But what puts me off is this 'framework' dependent programming. It is just frustrating. Your knowledge of framework just doesn't stay with me. And I really don't learn anything fundamental.

[+] leetrout|7 years ago|reply
I invest in my tools and learn a bit more than what I need to make them functional. This isn't always a tech deep dive- sometimes it's just being a "power user" and knowing the shortcuts.

I haven't met a recent grad in the workforce that uses git to its potential. They cargo cult workflows which is a good start but get in to trouble by not understanding just a bit more about how you can make temp branches / rags to keep from destroying commits in a rebase or how to prune duplicate commits from a sloppy rebase.

For terminals - using tmux or screen and understanding how they work enough to pair up on a remote box.

For any language knowing how to debug and how to profile. Understanding that print/println/log debugging is great and just keeping moving when figuring out why something isn't quite right.

This isn't a hard answer to what you asked but it's what popped up in my mind.

[+] LocalMan|7 years ago|reply
Your description of git raises a 'code smell' with me. I've found git to be far too complex to rely on. No, I don't have a replacement for cooperative development, but the thing is a bug trap (it leads you into complexity, making errors, and so on).
[+] majewsky|7 years ago|reply
> I invest in my tools and learn a bit more than what I need to make them functional. This isn't always a tech deep dive- sometimes it's just being a "power user" and knowing the shortcuts.

If you (the asker) are using a Unix environment, I would recommend that you set up a weekly appointment, maybe every Friday, where you sit down and read a random manpage. Not for the sake of memorizing everything, but to learn what your tools can already do if you just remember to look up the right invocation when you need it.

[+] davidwihl|7 years ago|reply
Learn about data, data science, statistics with a guise towards Machine Learning. Learning about data and statistics will give you a skill in numeracy that will be very distinguishing compared to the majority of developers (as evidenced by the other comments). This will help you quantify your accomplishments, ask thoughtful questions about the numbers others (including product managers) use to make decisions and give a fresh perspective to arguments that often lack credible facts.

Taking this further, with more math, can lead to proficiency in Machine Learning, which I think is the most important change in computer science in the last ten years, and likely very important to all developers in the next ten.

Background: started three companies (IPO, sale to a big tech company, crash'n'burn), CS degree from an Ivy, now working at Google.

[+] captn3m0|7 years ago|reply
1. Learn to Ship

2. Read everything on this list: https://blog.codinghorror.com/recommended-reading-for-develo...

3. Learn to go down the stack. The best engineers I've worked with know their stack deep.

I wrote a blog post on this once (targeted at recent graduates, should be helpful): https://captnemo.in/blog/2015/10/12/get-better-at-software-d.... The list on the blog post is:

1. Join a community.

2. Contribute to Open Source projects

3. Write all code publicly

4. Do tech talks

5. Stay Updated

6. Learn more languages

7. Concepts Matter

8. Ship Products

9. Have side projects

10. Read technical books

[+] __exit__|7 years ago|reply
Knowing a stack deep is rather difficult when one attempts to also learn and keep up-to-date with the newest technologies. Or were you referring more to system/protocol stacks instead of programming languages/frameworks?
[+] agitator|7 years ago|reply
If you are working at a new job, ask questions, ask lots of questions. The more you put your ego aside, and focus on absorbing everything like a sponge, you will leap ahead of your peers and your early career will set you up for long term success.

Often times, imposter syndrome will keep people from asking questions out of fear of being judged as incompetent. Let me tell you, the people who immediately ask about what they don't know are the ones you want around, the ones who pretend to know, or struggle through issues, or end up with odd solutions that need to be reworked take up more time and cost teams more money. The more you seek to understand form other more seasoned engineers, your peers, etc will only benefit you and will also have the added effect of building relationships and respect from others that will also set you up for a better long term career.

[+] PopeDotNinja|7 years ago|reply
Learn to pay attention to that feeling that tells you an abstraction is missing. When you try to bring something to life using the tools you know & it starts to feel much harder than it should be, that's a good sign there might be another tool out there you can use to get the job done. If you can't find anything, that's a good time to start asking if it makes sense to try a different approach or build your own.
[+] codingdave|7 years ago|reply
Like many questions, it would be easier to answer if we knew what your goals were. Do you want to grow into being the lead software person in a small company? Found your own place? Be a contributor in a large space? Work in academia? Teach? Be a digital nomad? Do design-driven web work? There are hundreds of choices of where you can end up. And they all result in different answers. So if you'll pardon a cliched question -- where do you want to be in 5 years? What would that person know? The answer to that question is what you should be studying.
[+] jmeiha|7 years ago|reply
Interesting - you've pretty much hit the crux of my issue. I'm pretty aimless right now, which is a big part of why I struggle to make choices on things like this. Setting definite goals is something I've always kinda danced around, it would be good to build up a habit of doing so going forward.

Thanks for the words of advice, definitely has me thinking.

[+] VargasTheOld|7 years ago|reply
The basics, the stuff that is one or two levels of abstraction below the 'normal' stuff. Write a compiler, write a query optimizer for an open source SQL database, write a new IO subsystem or memory allocation subsystem for MINIX, write a kernel for a Vector PU in, say, CUDA. Write a 4k demo in assembly. Grab a soldering iron and built your own mouse then write a driver for it. Write your own TCP/IP stack.

When I was a student, way too many years ago, the Uni I attended was very heavy on theory, lots of discrete math, physics, calculus, Big O analysis, electronics and computers architecture, Lisp, Prolog, CLISP, data structures and algorithms, wide search vs deep search, rebalancing red black trees on paper, etc. At the time I was very unhappy about it, I thought "why are they not teaching us C++, Visual Basic and this new language called Java that it's clearly the future?" But now, twenty years later I am very happy with the formal education I got. Having an understanding and an intuition of how things work all the way up and down the stack from transistors all the way up has proven invaluable during my professional career.

[+] vinayms|7 years ago|reply
The most important thing to remember is that technology of all kinds, software frameworks and even programming languages themselves come and go, mostly affected by the whims and fancies of the megacorps that own them, or the communities that eventually implode into a thousand forks, whereas abstract design and techniques, aka algorithms and analysis, are forever (well, as long as we stick to the Turing machine model). It might seem boring and disenchanting for a recent graduate to know that the "dry and boring" stuff he just got done with will be recurring forever, but that's the way it is (if you are creative then nothing is dry and boring anyway). Even things like design patterns and best practices are basically product of the technologies and the general state of affairs that people had to wrestle with at different times, so they have a shelf life and must be reevaluated before application, without succumbing to cargo cult or taunts and ridicule. These things are after all opinions of few influential people propagated by their minions (jk), and not laws of nature as observed and analyzed for centuries by great minds. Its alright to have counter opinion as long as its not contrarian just for the sake of it.

The second thing to keep in mind is that computer science/software engineering is basically like metallurgy - its purpose is to produce tools to make lives better, mostly for STEM people but also for laymen. So, while its perfectly alright to have some fun building sand castles in the foundry, it must be remembered that there is a greater purpose. An offshoot of this point is to pursue your interests in non "tech" field of your choice by getting away from computers every now and then; you never know from where you would get your ideas and where your ideas might have an application. As software guys we have an inherent freedom, much like artists, to explore other fields of knowledge, for it has benefits of many kinds. So avail it.