Advice to new programmers
olafurw.com
olafurw.com
There's one thing I'm sure was mentioned a lot by 17.1% of the participants, but it's one thing I'd like to stress:
Find a good mentor!
I've been teaching my son programming steadily for a few years now, and every so often he likes to take what he just learned, go and revisit some old programs he wrote or read from before he understood the new concept, and understand it better and often improve on it a lot (even rewriting it sometimes), and then he comes back to me very excitedly telling me how the new concept I taught him greatly improved the thing he did.
He's already writing code better than I did when I was a decade older than him, easily grasping new concepts like linked lists, garbage collection, pointers, and Lua coroutines and so on. When I was his age, I was still struggling to understand arrays in QBasic, had nobody to mentor and guide and teach me, and was generally pretty lost. Having a mentor who can guide you carefully and at your pace is an incredibly powerful shortcut.
Find a good mentor!
At my old Hackerspace, one of those high school robotics teams came to us for some help. The kid who was doing coding could really have used that advice. He confessed to me that he didn't have time to read through all of the controller framework code and understand it completely. We were under coding marathon conditions at that point, so he wasn't far off with that. One of the motors they were using was pretty big, though. Plenty big enough to seriously hurt someone. So I urged him to at least set breakpoints in all of his stubs, and step through those in the development environment at a minimum. He was pretty dismissive about checking his work. Downright smarmy, actually.
Sure enough, something goes wrong, and the metal body of this robot ends up spinning wildly, right in the middle of the team huddled around it, sending parts flying everywhere. Miraculously, no one was hurt. Did that kid learn anything? Nope. He still knew it all.
Right on! One of the most valuable skills I've learned over the past several years, is how to decompose your projects into small pieces, then decompose those things into even smaller bits and keep going until the pieces seem downright stupid. That last part is the key. You have to keep going until you'd feel insulted if someone asked if you could do those things. This sounds bad, but it's actually a very powerful mental tool.
Let's say you want to build an MMO. That's a really huge, complex chunk of work. So let's just take a piece of that, let's say the networking part. That's still really huge, so let's just take a piece of that, like the part that synchronizes the client's ship position. That's still quite big, so let's just make something that can send some kind of data between some clients and a server. Well, it turns out there are a bunch of tutorials online for building a Websockets chat server, so let's just start with going through one of those.
Then, when you can send/receive data, write a game loop simulation of an Asteroids ship, and build it into the server. Then, for a client, forget about networking altogether and go through a Javascript Asteroids tutorial. Next, sync those two in the stupidest way possible. Then, when that's working, make your sync just a bit smarter. Rinse and repeat. This is actually how I started building my game server.
(You can see a sort of reverse chronological order of this process here:
https://www.youtube.com/watch?v=7x2uQjLtXkY&list=PLnAL8xf0QQ... )
Asking for help was a sure way to be mocked by your fellow students, who for some reason lived by the idea that it's okay to mock people for not knowing something they do know.
And then lab professors saying it's not their job to explain things, just google it. I was literally told several times by the lab professors that "we're just teaching you how to effectively google things".
I wonder if that contributed to my hating bad documentation and guides.
I might not know everything by any means and generally provide a couple potential ideas, but 6 months later and they come and say "yeah you were right"
I may be petty but I've said "no fucking shit"
People actively seeking a mentor are likely willing to consider the advice and tough criticism they get as points to self-reflect upon, because they want to improve. They want to become faster stronger developers. As common as that might sound I have found intentional yearning for self-improvement to be rare or severely misunderstood among junior developers in the corporate world. More common than self improvement is interest in specific technology stacks of the moment and persuit of near instant gratification.
EDIT
Actually, I can remember observing this behavior once as a junior developer. When I started learning JavaScript 12 years ago the real big deal then was Java. Compared to me at the time everybody seemed incredibly experienced and talented, but most of the developers were negligent to the point of horrid incompetence at the frontend skills even though this was a big brand web business and 90% of their efforts generated frontend code.
There were a few Java developers who did have a solid understanding of the frontend code, but they intentionally didn’t advertise this. I had to actively observe for it. After badgering some of these people it was clear they were willing to provide mentoring if I asked for it and worked my ass off to chase it.
What I learned the hard way is the people who made the best developers had a secondary skill they actively thought about more than their primary skill and used that to reinforce their primary skill. At first it was Java developers who had a solid grasp of things like CSS, but I also saw it in others who were working out product management skills or business pricing logic more related to finance than programming. These people also tended to make strong mentors. The people focused on only their primary skills weren’t as capable and didn’t seek mentoring themselves or have much to offer other junior developers.
I do agree that trust is huge for mentoring.
But I think a lot of that is a lack of confidence and experience. It's hard to talk about this without sounding like a gigantic ass because no matter how I put this, I can't find a way to express how much I really respect other developers. However, I've noticed that there seems to be a big reluctance for actually reading and appreciating the code in the tools people use -- almost as if there is some magic seal on the code and despite it being open source, we are not worthy to gaze upon the code. I think there is a fairly large amount of hero worship going on and a kind of herd mentality. To question the laws that were handed down from on high is blasphemous (almost literally). It is to the point where many people feel that they are transgressing badly if they even deviate from the "community approved" coding standards. Thank god for auto-reformatting tools is all I can say!
When these same people see their colleagues, they realise that it's just some other goofball like themselves. Their colleagues are struggling, making mistakes, rewriting, grinding away. So I think there is a kind of group impostor syndrome going on where they think, "Well, that guy isn't that much better than me and I suck!" What they don't realise is that their heroes in the FANG companies and their nameless horde of community members are just goofballs too -- struggling, making mistakes, grinding away.
I think as well, we often see projects and people fall from grace. Some project grinds to a halt, or the horrible problems it's had from the start become more obvious to the horde. And then all of a sudden it's, "That guy is a joke. Only morons would use that framework. All the cool people have moved over to <some other equally flawed thing>". But again, I think it's just part and parcel of a lack of experience and confidence. Most young devs are secretly, desperately hoping that somebody out there knows "how to do it right". They get disillusioned quickly when they discover that their heroes don't know how to do it right.
And of course, nobody does ;-) But that's a hard message to sell.
I’m talking problems with the core functionality just not working.
I don’t think this is the case for other languages. Is it just that JS is the new hotness?
Good point, you can't force it on someone. What you can do however is explain to new programmers how valuable it is, this is not innately understood. The years where I had someone mentor me were the years where I made immense progress. Even though neither of us even considered it mentoring at the moment.
I've been successful in my career but maybe I'm leaving something on the table?
I once had a good manager who explained to me that perspective is like looking at a room through a small window. You can only see part of the room. Other people are looking through other windows, and likewise can only see a small part of the room. In order to see the whole room you need to see what the other people see. You have to go where they are and look through their window. It's the only way to piece together the whole picture. Even if you have the best window and the best vantage point, it's still better to give it up for a while and take a look at the other vantage points.
So, it doesn't really matter who you pick as a mentor, except it should probably be someone who sees the world differently than you do. And it will be really, really annoying for a while (maybe a long while) ;-)
At least that's my gut feeling...
> It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration. https://wikiquote.org/wiki/Edsger_W._Dijkstra
>The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offense.
Please stop dropping this empty-yet-well-meaning line - you're not the only one in this field who does this, either. I understand that it's not with ill intentions, but it's a feel-good line that people with experience like to drop on the internet as a catch-all piece of advice for how to develop software competency. The mentorship culture doesn't permeate nearly as strong as many of you think. Smiling and going "find a good mentor!" hides the complexity of the task and is disingenuous - it's a task that is limited by physical geography, electronic geography (the online communities one frequents), workplace culture (for the employed), and sociability of all parties involved, and a task that changes based on whether or not the recipient of this line is employed or in higher education at the undergraduate level. It can even be limited or change based on the mentor-seeker's current tech stack.
I would imagine most mentorship is of the incidental kind that just happens as you work with colleagues and some of them teach you things that take you to places you wouldn't necessarily have gotten to on your own. You may in turn do the same for others without realising it.
Definitely working alongside good developers naturally benefits you greatly.
So how do you, who are comparatively more experienced than your peers, not lose your patience?
EDIT: replaced 5x instances of loose with lose. Oh god. I was kinda' drunk and would be tempted to blame auto-correct on my mobile device but I just tried it, and it doesn't turn lose into loose. So I must just be a idiot.
Ask if they tested it, if it worked. Let them use git history
Continue your work, help with the third time
I know you mentioned that, but often times asking that question makes people try again, or doublecheck what they are doing. Giving them the couple of hours gives them room to maneuver and _maybe_ save face. Do it a couple of times and the people with good intentions learn to learn.
I lose my patience when the documentation is awful. I lose my patience when searching gives hundreds of irrelevant results. (I literally looked up a command today and half the page was dedicated to telling me how to not change a password with the password change command.) I lose my patience when simple things are hard, when systems aren't self-explanatory, when I get text dumps of nonsense rather than what I need, and when have to spend half my time wrangling with finicky tools and processes built by the people who came before me. And I really lose my patience when I realize that nobody values my time except when it wastes theirs.
I say this as someone who regularly asks for help I shouldn't need to: I can't remember our processes and policies because there is no structure to them. If anything goes wrong, there's 50 places I could look to find a solution, and knowing which ones to use and when is a process of memorization, and getting it right is so unrewarding that I'd rather not try at all.
Curiosity is having a problem and caring about finding out why it isn't working. Grit is having the resolve to keep chipping away at the problem until it's solved. Patience is realizing that things take time.
Whenever a junior starts asking me things when I'm on a deadline, I politely tell them to "keep looking". I'll potentially provide a hint if it will help. Some get annoyed and scoff at me and tell me "I've been searching!". Others keep looking.
That's it. And I have the feeling that with programming being considered as a lucrative career a lot of people come into this profession that don't have these qualities and would be better off doing something else.
- Asking a question can be humiliating, especially if you are expected to know its answer. When a junior asks me something, I keep that in mind.
- Things that are obvious to me are not obvious for juniors. They might know X and Y but have no clue how to draw a line between them. They might not even know an alternative exists.
- If the junior does not come to me with a question, he might spend 20x actually needed time on the problem. Helping juniors is one of the best ways to meet deadlines.
- Regularly helping someone establishes trust and makes it easier to delegate to them later. More of my time saved.
- The main thing that I am teaching them is patience, I lead by example.
- I focus on explaining how to them more than what, even if I spend an hour, or have to do a pair programming session. If the lesson gets ingrained I just helped save a heck of a lot more time.
- If the same kind of questions get asked a lot, I create a doc or a recording and reply with a link.
- Different people need a different approach. It is quite likely that I am doing something wrong in how I provide help. If the person trusts me with questions but does not seem to adopt the advice, I sit down and have a "crucial conversation" with them to figure out if this is the case and adapt my behaviour.
- Some people are just stupid.. "Against stupidity the gods themselves contend in vain". Knowing when things are out of my control helps me avoid stress. That said, this is the very last resort, and rarely true. I usually try everything else before I start brushing people off and saving time for others.
*2000x. Very true.
> Different people need a different approach. It is quite likely that I am doing something wrong in how I provide help.
A thousand times this. If you think they couldn't possibly misunderstand you, think again. Then again. Every time.
> Some people are just stupid.. "Against stupidity the gods themselves contend in vain".
Sure, but check with someone else--someone outside of your comfort zone--before confirming that.
I want people to feel confident asking me questions, so I will never treat a question as nonsense or a waste of my time.
For starters, I try really hard not to think of the professional engineers on my team as "juniors." They're adults with thoughts and ideas and a different context than me and they're better than me at many things. Thinking of them as juniors in my mental model makes it way too easy to condescend to them and be patronizing.
Second, what is one's value as a senior engineer? A senior engineer is usually expected to be a leader. People will follow a leader's examples - not just in writing code but how he carries himself. If a leader loses his patience, his team will think that is acceptable behavior and start trying to get away with it.
In the context of a senior programmer - they can only accomplish so much on their own while coding. They bring so much more value to the group by helping their teammates be better. That manifests itself in code review, in being present and available, in providing reassurance to people finding their footing, in answering questions, in showing people how to do things, and just being an all around mentor. You can bring so much more value to your group by elevating your teammates to your level, rather than being the lone all star.
Third, I would try to think about this from their perspective. They're probably worried they're not doing a good job, they're probably feeling some heavy imposter syndrome, and they probably look up to you as someone who knows what they're doing. They have no clue what you know and don't know, or why you wouldn't know something. Cut them a little slack and realize that you have a presence among them, whether you're aware of it or not.
Fourth, think of this practically. You're squandering so many opportunities to teach and help the engineers on your team grow. I love when someone comes to me and says, "this doesn't work," because it is such a great chance to teach someone how to use precise language to describe a process, which is a very important skill in software engineering. It's a great opportunity to show someone how to debug a problem!
When someone asks you something you don't know, and you lose your patience, you miss a huge opportunity to show them how to find knowledge themselves. If you'd said, "I don't know the answer to that question, swing over here and let's try to find it out," and then you drove through some searches and articles while they sat by, you could show them some of the things you take for granted - whether that's how to skim search results, what to search for, or just knowing your tools like keyboard shortcuts.
So I'd say try to reframe how you look at things and how you look at your own role, and how you look at yourself. It might be helpful to look at advice other types of leaders have - NCOs (Non-Commissioned Officers in the military) or Sergeants in police forces for example.
I am OK with this from time to time but there are plenty of people who are simply too lazy or incompetent to figure out things themselves and want somebody else do things for them. I generally enjoy helping but I know people who even after I type their question into StackOverflow right in front of them and read the answer to them they still don't get the hint to look up things themselves.
Oh boy, this is a deep topic, but generally speaking you have to come to the realization, that losing patience is almost never in your own interest. When you are faced with incompetence or laziness, or being accused for something clearly not your responsibility or fault, it's very easy and natural to let anger dictate your response. It feels right and justified.
But this is not to your benefit. Because your goal is not to defend your standpoint against an opposition - a quick shortsighted affirmation, that you are indeed "right". But to resolve the situation in a calm, rational & constructive way. In the end you can only win, when everybody wins, and that is your real goal!
And you have to incorporate that mindset and live by it. Doesn't matter if we're talking about work issues or getting angry about people in traffic.
On second point, some people need to hear that discovery and googling and figuring out and trying wrong options until you stumble onto right one is what they should do. It is not just matter of laziness, some juniors think that if they are confused and lost they are wasting time and something is wrong. They need to hear that it is ok and normal and that it is their turn to train figuring out part.
When you help people too much, they may become too used at that and wont realize when they are ready to start the harder part by themselves.
Then I got kids and I finally got it.
Loosing patience DOES NOT HELP. Ask yourself "What I am trying to achieve here, with this young padawan asking me questions? Are those questions stupid? What is the underlying reason the padawan asks the question? How can I maximize my help, what kind of response to the question supports what I want to achieve the best?"
Anyway, loosing patience only puts off the padawan and while it may help you achieve the immediate goal of not having people ask you questions I think it is just bad long term strategy. Senior people are traditionally meant to help shape younglings. If you make them not ask questions then you are very likely not doing an important part of your job.
I've come a really long way and I'm proud of how far I've come. At the same time I definitely have moments where I interact with someone else and think I'm still such a novice. I am much better at when this happens, being ok with it being true and using it as motivation to keep learning and get better.
I think long term managing that frustration... is 90% of the battle for me.
I learned after age 40 and my patience is so much better than when I was younger. I suspect it has helped a great deal.
'The more you learn, the less you know'.
Now say it to yourself.
Often you find it used to be done that way in the past and then they stopped doing it that way because Y. It turns up all kinds of interesting stuff that no amount of thinking will get you to on your own.
That would be my number one advice for those starting out.
In my class, our textbook was "The Elements Of Programming Style" by Kernighan and Plaugher. As far as I'm concerned, it is THE book for beginning programmers. It's rare and expensive now, but worth it.
In a nutshell, it taught:
- program in a direct way, do NOT try to be clever and code in weird, complex ways. Your code (not just the comments) needs to be readable to others, what it does should be evident. (The book gave examples of both, and after looking at a number of these examples, you get the idea of what K&P mean by ELEGANT programming.)
- Subroutines must have one entry point and one exit point, and accomplish one task.
- Add lots of comments in your code to help others or even yourself in case you forget what your thinking was.
These are just a few examples of good programming practice. I later became a professional programmer, using assembly language and C++. But that first college book was the one that outshone all the later ones that I read. Get it if you can find it!
I would also highly recommend Dennis Ritchie's books.
One more thing - object oriented programming is good, but I'm not sure it's paradigm will win out in the end. As an assembly language programmer, I began to realize the power of data driven programming, and I began to write my programs in that way. Which is why I think this new language, Julia, holds a lot of promise. I say this as one who has only read ABOUT Julia, not as one who has studied the language itself.
Sometimes code is much cleaner if you exit a method or a function early. Especially in languages with automatic memory management where you don't need to concern yourself about leaks so much.
> - Add lots of comments in your code to help others or even yourself in case you forget what your thinking was.
Lots of comments is a red flag to me. It often indicates the code itself is of poor readability. But it's usually easier to just slap some comment on it than to properly rewrite it... "A comment is a failure to express yourself in code" (Uncle Bob).
> These are just a few examples of good programming practice
I'd argue they are debatable, and at the very least not necessarily universal.
But I get what you mean, and you make a valid point.
What I learned though is that a lot of programmers suffer from a form of a "comment blindness". I was once asked to explain a piece of code for which I already provided that exact explanation in the form of a neat, verbose comment, on this every screen : )
In my experience, programmers develop this "comment blindness" kind of like an everyday person numbs themselves to omnipresent ads via so-called "banner blindness".
Basically, most of the comments one encounters are redundant, stale etc. and therefore useless. So the less comments overall, the better the chance for the ones that matter to stand out.
At the end, there's no silver bullet, and while as experienced programmers we find it obvious and needless to say, I guess it probably is a valid takeaway for juniors to take most guidelines as rules of thumb only, and avoid falling into dogmatism (the mother of cargo cult)...
I agree, comment judiciously.
Your example is good about learning good program structure; that can save you a lot of time. You can only learn so much that way though. Sometimes you just have to make mistakes.
I've written a lot of code that is bad. But if I hadn't written that code and I was tasked to do again I'd do it the same way because there is no other experience to tell me not to do that. My sum knowledge of programming is everything I learned from school and from reading -- but the majority comes from actually writing a whole lot of crap.
It's interesting but in my experience:
> Subroutines must have one entry point and one exit point, and accomplish one task.
My subroutines almost always exit early at the top if any pre-conditions fail to be met. This is much better than a ton of nested if statement for each pre-condition. But in general it's best not to exit somewhere in the middle.
> Add lots of comments in your code to help others or even yourself in case you forget what your thinking was.
In practice, comments are pretty hard to maintain. I usually ask new applicants how they ensure a project can easily be passed off to others and if they just answer comments then that's generally a bad sign. Good hires will often laugh when mentioning comments and then describe other things like good naming, etc.
I code often as a statistician and data scientist, but am at a point I need to learn better craft. I'm all ears!
https://www.amazon.com/gp/offer-listing/0070341990/ref=tmm_p...
The lacking part is not knowing what you are doing (if you know what you are doing, why do you need to practice?), but having enough introspection to be critical of the code you just wrote.
Good thing every programming language nowadays enforce that lesson. I can only imagine how horrible it must've been to reason about a program when a method could just GOTO away and never come back.
The "one page ahead in the manual" quote is a great example of this. It's hard to remember when you didn't know everything you know today -- so think about yesterday, or last week, some smaller time slice. What did you learn yesterday that somebody on your team may not know? Operating at that layer and sharing knowledge freely shows you're a friendly resource and shows that you're honest about your journey. It attracts other people who are slightly above or below that level, who can share and multiply what you're learning.
(And it has a great byproduct of teaching you where the egos sit at your company.)
When I began programming, I was forced to use vim and hated it, I didn't understand why someone would use such an "old school" text editor to write programs. I abandoned it and moved on to typical IDEs. As a young programmer, it's difficult to see the value.
But many years later I discovered the power of vim came from customizing it to my exact preferences, and mastering all the shortcuts and its grammar. After a year's worth of effort, I began coding at the speed of thought, and programming has been much more enjoyable ever since, as time moves on I only get faster and faster. It's like cooking with a really sharp knife vs a dull one.
nnoremap <F5> :w<cr>:!printf "\033c";python %<cr>
and now I can execute a Python script I'm editing with one keystroke instead of "save, exit, ./myscript, vi myscript".set makeprg=python\ %
Vim comes with the :make command which is handy for compiling projects with Makefiles. But you can also set a different value for makeprg to do whatever you want for the current file. Of course you still to set up a key binding in your VimRC:
map <F5> :make<enter>
> instead of "save, exit, ./myscript, vi myscript".
This is something I see a lot of people doing. Obviously, it is not efficient. There is no harm in having another terminal window open where you run the script. If you are using SSH, you can use tmux or screen to have several terminals in one SSH session. And lastly, if you have to edit several different files, do not exit vim to switch files. Learn to use the :e and :b commands.
(The last advice is meant for the general audience and not directly to the previous post's author)
Build something that solves a problem and put it on github.
Not only are you adding to your portfolio, but you're demonstrating that you can take a problem and come up with a solution for it. Canned "To Do" apps aren't as impactful because there's a 1000 tutorials for this online and everyone knows it (though they can still help for showing knowledge of a technology or stack, so don't count them out)
"When you don't create things, you become defined by your tastes rather than ability. Your tastes only narrow & exclude people. So create."
And there was a time when a snotty admin convinced me that he had the authority to require me to do development in vim. He did not, and damn that learning curve was steep- but I picked up skills that still serve me well a couple decades later.
Oh, and another one - we had a process for cranking out custom reports, where if you could express the entire thing they were asking for in SQL, then you were done. But if any part of required programming logic, you had to create a controller, and a template file, and register them, and do a full product release... it was a big hassle. And man did I ever learn how to make SQL jump through hoops at that job.
So, a corollary to your "The longest way is the shortest way" is my life lesson - Constraints make you better.
I really wonder if that admin was more of a 'bastard operator from hell' (old school reference) or sneakily getting you to improve yourself.
Ha, yes, he absolutely was. Just very lazy, knew I already had SSH access to our staging server, and knew I needed to develop on there, but didn't want to bother setting up SSHFS and configuring it to be accessible from my windows machine, and didn't want me telling him to do a new staging deploy every 10 minutes while I tried to figure out how to get some connected hardware working right.
For those unfamiliar with the development experience, its very similar to scratch but with a spreadsheet-like layout.
When I seriously started learning the workings of more complex logic in these tools is when I started reading the "source code" of the 2d platformer Zeb, programmed by Lee Bamber (who would later go out to make Dark Basic), drawn by Nolan Worthington.
This taught me in a very condensed manner lots of advanced programming techniques. Like a teacher of mine used to say, this will feel like drinking Fun Light (concentrated drink supposed to be cut like 1/12) directly out of the bottle.
And that tradition has stuck with me, decompiling dlls and inspecting websites etc.
Open source projects (whether corporately funded or hobby led) are run by people! So it's in your best interest to give before you take. Become active on the communication channels, answer user questions, fix issues where you can, etc... Once the lead developers recognize your name, they will be more willing to review your code (and get your changes merged when review bandwidth is low). Well run projects often have very knowledgeable people that can point out mistakes and teach you in general.
Of course, there's still value in being a "drive-by contributor" where you fix a small bug and never come back. It's just unlikely that you'll form any sort of relationship from such an interaction.