Hacker News new | past | comments | ask | show | jobs | submit login
Advice to young programmers (chestergrant.posterous.com)
111 points by chegra84 on July 23, 2011 | hide | past | favorite | 63 comments



I would also add this: don't join a priesthood.

In other words, keep your mind open. Don't become a ___domain expert, as advised, and then convince one's self that that ___domain is The One True Path. Conversely, don't glance at a particular ___domain, assume that casual knowledge to be canonical, and then write off that ___domain as A Path of Fools.

Young programmers are especially susceptible as the myopia of youth prevents one from grasping the miniscule nature of their own knowledge. Once one gets a bit older, he/she tends to realize that what they know is but of grain of sand in the ocean.


> Don't become a ___domain expert, as advised, and then convince one's self that that ___domain is The One True Path

I first parsed this as "Don't become a ___domain expert, as advised. Also don't convince one's self that that ___domain is The One True Path".

Lest someone else confuse it the same way, this does not imply that becoming a ___domain expert is wrong; it means that after you become a ___domain expert, you should still keep an open mind.


Importantly, ___domain expertise is how you get to the big $, which I'm sure is of interest to most young programmers... The amount I can get selling myself as a developer with expertise in my field over selling myself as a generic developer in some other field is quite substantial.


Yes, that was poor phrasing on my part. It should have read something like "By all means, become a ___domain expert, but don't convince..."


Meh.

As I've matured, my confidence in my own knowledge has only increased. People who play the "It is a truly wise man who knows he is not" card are usually trying to limit you. The main thing to keep in mind is that your intelligence doesn't preclude others from being intelligent either. Have confidence in your abilities, but don't let that stop you from having confidence in others' abilities.


> People who play the "It is a truly wise man who knows he is not" card are usually trying to limit you.

I've always felt just the opposite. Acknowledging what you don't know can furnish you with the drive to learn it - thus becoming better. Understanding you're not "wise" is the first step to becoming so. The moment you get to confident in your abilities is the moment you stop learning.


I'm very confident in my abilities, and learning new things is my favorite thing to do. One can be confident without facing petrification, just like one can be unconfident and decide to give up learning new things.

I'm not saying this point of view doesn't have its place. I just think it's important to understand the dynamics involved with it. You don't tell someone they don't know as much as they think they do unless you're trying to stop them from doing something (you feel) they shouldn't be doing. Trying to paint it as enabling them is disingenuous. If you want to enable them, you have to work to help them learn good behavior in addition to limiting the bad behaviors.


I think I understand what you mean, but I don't think that's what the comment your are replaying to is all about. I think it's good to do both, trust in your knowledge (and so don't "join a priesthood") and still know that you "nothing" (or just a tiny bit).

Hmm, or maybe I didn't understand you or the first poster and that's what you meant. Sorry, I'm a bit confused right now.

Also I wonder how many people ever read this. Most of these things you'll realize sooner or later as it is what really makes you a good and experienced programmer. I'd just suggest to be open minded and think for yourself, but I guess that's a good suggestion for your whole life.


Good advice.

The way I read "become a ___domain expert" was not really as an expert in, say, Java or .NET, but in an area like web development or game design.

With a less technology-based focus it's easier to avoid One True Paths as you have a better perspective on (and soon a better knowledge of) the alternatives to whatever you happen to be using at the moment. It's also easier to stay knowledgeable when things change.


"I know that I know nothing, therefore I am wise." - Socrates


My only advice, to all programmers, is to print the following and stick it in a place where you can see it everyday:

“There are only two hard problems in Computer Science: cache invalidation and naming things.” – Phil Karlton

The variant mentioning off-by-one errors may be pleasant, and useful for beginners, but is hardly a problem.

When we'll have solved the naming thing we'll be safe.

The rest is just buzz-words and useless noise.


This quote is fine to use for fun/irony, but should absolutely not be taken seriously.

Some seriously hard problems in computer science: distributed programming (consensus, consistency, handling machine failure), parallel programming models, proving correctness of nontrivial programs, P?=NP.


Those are all special cases of the cache invalidation problem.


I knew someone would try to say that. If you take that line, then everything is cache invalidation. It's amazing the lengths people will go to to justify wise-sounding-but-wrong sayings like the above.

Cmon, P?=NP is cache invalidation? Be serious.


All the distributed/parallel stuff is, yes.

It's not meant to be a literal, pedantically correct statement, it's meant to be an insight, and enough people think that it is that this quote gets repeated. By all means print out your own page in 4-point text of what is and is not a hard problem and stick it on your own wall.


Consensus is most categorically not cache invalidation. Consensus is about creating new information, namely a decision about which a group of machines/processes agree.

It's not insightful if it leads people to the wrong conclusions. It would be more insightful to impress on people that CS is a large and diverse field with more hard problems than can be reduced to a single pithy saying.


Naming things is a hard part of programming, but that doesn't make it a computer science problem. Computers can't name things for us. To solve the naming thing would be to solve the thinking thing.


> My only advice, to all programmers, is to print the following and stick it in a place where you can see it everyday: “There are only two hard problems in Computer Science: cache invalidation and naming things.” – Phil Karlton

I am curious as to the reasoning here. Why are these 2 the only hard problems in computer science?


They aren't: http://news.ycombinator.com/item?id=2798475 I don't know if the person being quoted was being serious about this, but do not listen to anyone who repeats this quote intending for it to be taken seriously.


"The variant mentioning off-by-one errors may be pleasant, and useful for beginners, but is hardly a problem."

On the contrary-- I have seen many beginners struggle for a long time to fully grasp counting starting at 0, which leads to many off-by-one errors.


That's right but with some very basic rigour that kind of bug ever hardly bites. With high level languages this is less and less of a problem; Python for example let one write code without using i.


5. Say yes ... No!

SAying yes is an implicit delivery promise. You will either break yourself (budget over runs, massive stress) trying to deliver, and/or you fail and your reputation suffers

If you have done it once already and know how much effort it will be - say yes and quote

If you have never done it before, say "I have never done it before" but for a small hourly fee I will implement a prototype. If you like it we can talk full project, but if not, or if I cannot make it work, then I just keep small fee as R&D.

The customer then has more choices / options which is usually appreciated

Dont lie to customers. And saying yes without saying "I've never done i before" is lying.


I totally agree - saying NO is one of the best things you can do. And also "I don't know" is ok as well.

I've been in high level meetings with business guys before and watched them say "yah, we can do that", knowing we could not. While, in theory, saying yes might be a 'positive step in the right direction', what it usually means is all engineers will be working god-awful hours to get the work done. What is done is then usually sub-par because there wasn't enough time to think about the problems to be solved. Sometimes, code and great architecture come quick. But more often is slow and iterative. Having insane deadlines and workload because someone says yes is just a bad idea all around.

But I would even step back a bit from the computer science aspect for beginners. One thing that was very hard for me was abstraction. When I first tried learning OO programming, it was very frustrating. The problems that people modeled did not make any sense. A car has a wheel which is composed of a tire, etc... I felt like I needed real concepts. I always liked the 'User'. A user has as name, age, height, etc. It can also have multiple addresses. Once you have basic info like this, you can start doing things with or to it. Authentication is a perfect example.

Having a concept (a key) that you understand and can work with and model - like the User example - not only starts you on your way as a programmer, but also provides the bridge to learning other languages. And when I was younger, this is exactly what I did, I brought my 'key' (a User/Person) with me, started small, and built out from there. This was before understanding data structures, algorithms, patterns, etc.

So my ultimate advice (besides staying honest and being able to say no or I don't know) is have a simple 'key' concept you understand inside and out. This can open all the doors later down the road.


I would also recommend learning at least the basics of lower levels of computing technology, e.g. some CPU architecture and some assembly or low level C.

It's a lot easier to avoid becoming a zealot when you know what's going on underneath.


Do you know any good resources to study this sort of thing from? (any summer programs?) I am a young developer and have been meaning to learn this sort of thing for a while.


If you want to play around with some hardware I'd recommend getting an Arduino board. You can start with the Arduino IDE and work your way down to the metal. It's a relatively simple system but the principles apply pretty much to bigger systems.

Another good platform in the same vein is the BeagleBoard, which is a great way to play with a slightly bigger platform running Linux.


kay and arr


Some good advice in this article. The most valuable thing I've picked up as a young programmer is the importance of finding your own learning style. Some people read books, some watch podcasts, some can just read the documentation and go. I've found that browsing example source code in the language/framework I'm using (with some light documentation reading) does well for me. It may take you too long to learn the skills, languages, or frameworks required by your post-graduation employer if you never took the time to find the best way to teach yourself.


This advice is mostly not harmful, but the most important thing a newbie programmer can do is actually just code. Just sit down and write some code. That's it.


I kinda hate this mindset. Programming is not about how much code you write, it's about understanding a problem and then coming up with a solution; writing code is but a small part of this process. If there is anything I have learned over the years it is that one should think first then code.


Here's the thing. Programming is incredibly complicated. Unless you're a robot or at least a lot more intelligent than me, there's no way you can think through all the bazillions of subproblems (many of them rather trivial) when thinking about how to solve a programming problem. You have to be able to solve those subproblems as they come up while coding. In order to be able to do that, you have to have a lot of routine. Writing a lot of code helps you get that routine.


You're looking too much into my phrasing. I don't expect someone to just sit down and write the same program over and over. The point is for them to come up with problems they want solved, and solve that problem with code. Thinking about the problem and the solution is a big part of the process, as you say.


"writing code is but a small part of this process"

Um...no it's not. And as far as understanding a problem goes, many times you do that by writing code, or don't truly understand it until you do.


I agree that sometimes just writing code is a good way to get started solving a problem however, I do not believe it is usually the best approach in general. Spending to much time planning can be a problem but many new programmers jump into writing something without even considering the problem much before hand. This approach very often leads to learning lessons the hard way, which I admit is not always a bad thing. In the long run though failing to learn to think and plan before you code can limit ones abilities.

Different problems call for different solutions and sometimes just jumping in and coding can be lots of fun but, on the other hand, some projects require a fair amount of problem understanding and planning. If you like to code but you don't enjoy hard problems (the kind that take real research) you eventually reach a ceiling in what you can do.


This response seems irrelevant. This is about a new programmer- not a project over ones head. The most important thing I did when learning = I sat down and wrote code, when I came across an issue, I learned how to fix it. And because of that - it taught me to plan my code better as I went


Programming is like building stuff out of Lego. Just grab a box of lego and start creating things. I don't think fun would be had if you had to think and design and plan everything before you built it.

The way to learn something, is to do it.


I think the code is the solution. If the code isn't written, the problem isn't solved.


word++


I don't know about those Deitel books. I had to use a Java one in college and did not enjoy it. Maybe they've gotten better.

Here's Peter Norvig's review of a Python title: http://www.amazon.com/review/R2C7L5KHUVHOR2/ref=cm_cr_rdp_pe...


The 'path' seems to be of a solid programmer/consultant. If you are going to work in a team then I would add 'improving teamwork skills'. This mainly involves respecting others in the team and focusing on team's success. These things go a long way and you will get a chance to work with developers in different areas of the company and contribute towards interesting projects.


He missed some important ones: study good code and practice writing it.


Where can I find good code to study? Also, how can I tell how good code is?


Greg Wilson often mentions that very few programming courses will incorporate the study of existing, proven programs and their code. This probably applies equally to self-taught programmers, and many programming books.

I recently bought and read Wilson's recent publication, The Architecture of Open Source Applications (http://www.aosabook.org/en/index.html). It focuses more on the architecture design for some well-known programs (Eclipse, Sendmail, Mecurial et al), but does include some code samples. The best aspect of it, IMHO, is that it focuses on the decisions the programmers faced when designing their code, and the tradeoffs they made.

The NoSQL chapter, in particular, is a really good read and should be referred to by all parties before any NoSQL / SQL flamewar begins.


Seconding my sibling richchan that it doesn't necessarily need to be "good" code, I'd suggest starting by reading the libraries — or even just the specific classes or functions — you like to use.

You already know what they're supposed to do, so they'll be a lot easier to figure out at first— and once you do, it will provide the immediate benefit of understanding your tools.

As for how you tell, a good rule of thumb is, the harder of a time you have telling how it works, the worse the code is. This is of course only a rule of thumb, but it applies doubly in the case of code where you understand well what it's supposed to be doing.


Sometimes this is a rather advanced project. Don't expect to have an easy time reading glibc, for instance.


Yeah, this is probably better the higher-level you're talking about. Also, I wouldn't start with standard libraries, since they'll generally be written much more for performance than accessibility.


There are many ways. One example:

On GitHub click on Explore GitHub, Languages, your language, "most forked overall" and choose what interests you.

Or in other words look up popular programs written in the programming language of your choice. Just be sure to not look at code that's too old, as it's more likely that they contain a lot of stuff you wouldn't do anymore. Especially true in the Perl world.


It probably doesn't even need to be "good" code. Just study any code and think about why it is written that way, and what circumstances makes it good.

Any correctly written code can probably be considered good. The rest is about how well it is designed and how it performs in different situations.


There are plenty of good code around. Study Linux Kernel if you want to get really high!! Basically, depends on where your interest lies .. find a good open source project in your area of interest and figure out how it works ...


Exactly. It depends upon which language, framework, programming style, etc. For game code you can look at ID's work. For java I hear the Jenkins code is very good. Ask around, there is no shortage of good code.

My point is that as an apprentice you should study the masters. Try and duplicate their work through practice.


Jenkins code is alright. It has a little bit symptoms of "being written by one man" (Kohsuke) to it but I wouldn't call it very good.

Here are a few projects with good Java code: Spring Framework (check mostly around the spring-core stuff), Apache DS, Google Web Toolkit APIs, Google Guava, Google Guice (pretty much almost all Google Java open source projects have similar high-quality).


I like this article, probably because I do as outlined in it - but I also wonder how this (or the first advice particulary) is applied to pair programming? Seing someone else solve an interesting problem over his/her shoulder while discussing it endlessly will never quite stick as when you think about a problem for days and then come up with a solution for yourself.


Pair programming should not involve watching somebody else solve a problem. A good pair programmer knows how to involve even junior colleagues in the hunt for a solution.

I agree that things stick better when they're harder. On the other hand, when pairing I learn ways of solving problems that would never occur to me. And it's not like when pairing nothing's hard; I think I have just as many in-the-shower ahas when on a team that pairs.


Pair showering is a good way to involve your teammates in these inspirational moments.


I think the main piece of advice is number 2. Make lots of small throw-away programs. Whether these little junk programs are good or bad doesn't matter - you will be learning something either way.

And post everything to Github (or Google Code, Sourceforge, etc). Having that kind of thing public gives you more of a reason to want to improve.


Think, then plan, then code.

Simplicity where possible, complexity only where required.

Be a code scientist. Take your theory about the bug, test your theory, then make the fix. Then test the fix.

Don't be satisfied until you really know what's going on.


I think his Point #5 should say "knock something OUT", not "knock something UP". If someone asks you to knock something up, you should probably ask your wife for permission first.


I'm not sure where you're from, but here in England if you knock something out you've beaten it unconscious :P



The author actually mentions "Bare[sic] in mind that there are multiple paths to becoming a programmer, and this is just my way of being a programmer."


I don't think seven "Become a ___domain expert" is a good idea and especially not something you should recommend. If yo really find the right thing you'll know, but it is very good to know a lot about everything.


The problem with that - and I say this as a generalist myself - is that usually you don't know a lot about everything. You think you do, but it turns out you don't. For instance, I've known "a lot" about web development. Now I have a new job that exposes me to ___domain experts in web development - and it turns out I didn't know jack.

There's nothing wrong at all with being a ___domain expert. Most generalists - again, I say this as one - aren't as good at everything as they think.


But you really should not strive for this. You will most likely become an expert in some thing anyways, but it usually makes people bad programmers, because they stick to stuff, simply because they know a lot about it. For example it's a very bad thing to know just one programming language and to know just one paradigm. It also causes you to always use old stuff. I guess it's one of the main reasons for everything using C, Java, XML even if there are things they'd actually prefer if they use about them. Same for servers, like Apache, the MySQL or relational databases in general.

You won't learn anything anyway, but I have been disturbed when I realized how foolish it was to stick to things, because I knew how to use them. Learning other things usually means that you gain a new perspective making you better overall, even when it comes to stuff you already knew a lot about.

The problem is also that it hinders you to even know about stuff you'd probably be very good at. IMO that's the biggest problems with this suggestion. Sometimes the thing that what looks hard and complicated to you becomes the thing you can't live without and eventually become an expert in. Maybe the 'sometimes' could even be replaced with 'often'.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: