Today’s link is a reminder that no matter how great you think your favourite language is, every language has flaws. Some people like to go around talking about how their favourite language is the best language and every other language sucks, but that’s much more about personal preference than it is about any one language being objectively better. Different languages are good for different things anyway.
Read a little YourLanguageSucks and don’t be a jerk about other people’s favourite languages :)
Many years ago when I was in college, a friend taught me something that’s been really useful for my whole career. That lesson was to let the computer do it for you. Unless there’s a compelling reason to do things the hard way, just let the computer make things easier for you.
Learning lisp? Get a plugin for your text editor or a simple IDE like Dr Racket that matches your parens for you.
Working with fixed width files? Get Record Editor, it’ll save you so much time!
If you have to do something tedious and fiddly, get the computer to help you. That’s what it’s good at. There is a tool out there that will make your life easier, you just have to go and look for it. The hard part is remembering to go look for it :)
It’s normal to think that if there was a tool you could use your teacher or your boss or someone on your team would have told you about it, but thinking to look for tools like that is surprisingly unusual. And to be fair, it can be a real timesink to try tool after tool just to find out none of them are better than what you’re already using.
If there isn’t already a tool, you might be able to build one. That’s exactly what bash or powershell scripting is for – fiddly things that humans are bad at and tedious but simple things that humans just don’t wanna do. If you’ve ever run a build script, you’ve used a custom tool that someone wrote to automate building your application so it gets done the exact same way every single time. No matter what OS you’re running, there will be other scripts out on the internet that you can take apart to build your own custom tools.
Whether you find tools or build your own, remember that boring stuff is the computer’s job!
How do you know when to take someone’s advice and when to ignore it? Today’s link lays out a few simple steps to figure out When ignoring advice makes sense. There’s no shortage or advice for programmers out there, but there’s just no way all of it works for every single programmer. If you have a process for evaluating advice, you can be sure that the advice you reject really doesn’t work for you. If you just flail around and try stuff, well maybe the things you don’t like really don’t work for you, but on the other hand maybe they just feel weird and that makes you want to stop and go back to normal before you’ve really given them a chance.
Go forth and ignore some advice, safe in the knowledge that you gave it a fair shot and it really didn’t work for you :)
Here’s my recap of one of the talks from that list, Hammock Driven Development by Rich Hickey. In it he describes his process for solving hard problems, which is obviously a huge part of what programmers do and is probably useful for just about anyone else too. There are a couple of technical examples in the talk but almost all of it should make sense to a non-programmer.
I put numbers on these steps to make this blog post easier to follow, but that doesn’t mean you have to follow this process in this exact order. The first couple of steps really do need to happen first, but after that you may want to iterate over the remaining steps a few times and possibly even go back to the beginning to make sure that you really do understand your problem in the context of all the new stuff you’ve learned while you were trying to solve it.
Step 1: state the problem. Say it out loud, talk with team member about it, write it down if nothing else.
Step 2: understand the problem. What do you know already (facts, context, constraints)? What don’t you know? For example, if you know you will need input data, where does it come from? if the primary source goes down, is there a secondary? Are there related problems? Hint: there are. Your problem is almost certainly not unique in the history of the world. And if you’re going to bother to figure all that stuff out, write it down!
Step 3: be discerning. Not everything is awesome! Look for problems in your proposed solutions and try to solve those too right away up front. Do you think there aren’t any tradeoffs in your proposed solution? Not likely, it’s much more likely you’re missing something. You should have questions – nobody knows everything! If you don’t have questions, you’re missing something. Write all this stuff down too.
Step 4: more input better output. You can’t connect things you don’t know about. Read in and around your space (not just your exact problem, also similar stuff so that you can let that simmer and let your brain make connections). Look (critically!) at other solutions too. Great solutions can come from tearing apart someone else’s idea.
Step 5: tradeoffs. Everybody says design is about tradeoffs, but you need to look at at least two possible solutions and figure out what’s good and bad about those things before you can really say you made a tradeoff. Write this down too! You may be seeing a theme here :)
Step 6: focus. This is where the hammock comes in. One of the great things about the hammock is that if you lie down with your eyes closed, no one knows you’re not sleeping and they won’t bother you because you might be sleeping so you can focus completely on your problem without interruptions. The computer is a prime source of distractions – you need to get away from the computer if you want to focus. You can’t do everything – if you really focus on something you’ll drop other balls like returning phone calls or emails, or remembering to run that errand or fix that bug you said would be really quick. Let your loved ones know what you’re doing and why you’re not going to be super responsive for a while (as an aside I really liked this point about treating people who matter to you as if they, you know, matter to you). An interesting detail Rich includes in this step is that you should close your eyes to really focus – at this point you’re not looking for any external input at all
Rich has a bunch of interesting stuff to say about what he calls your waking mind and your background mind (in the Leaning How to Learn course they call it focused and diffuse modes of attention, if you’ve taken that course this will all be pretty familiar). He uses his waking mind to assign tasks to his background mind and to analyze it’s products. Your background mind is where you solve most non-trivial problems but you can only feed it, not direct it. You need to spend enough time thinking about something for it to become an agenda item for your background mind to get anything useful from it.
Step 6 has two substeps, loading up your background mind and then letting it work. To load up your background mind you review everything you wrote down in the previous steps and really focus on it. Because your waking mind can only keep track of so many pieces of information at once (7 +- 2, as far as I know), you need to have written everything you know about your problem down so you can swap those pieces back into your working memory when you need them. To load all of this into your background mind you need to survey everything you’ve written down to give your background mind the chance to make connections between different things that your working mind didn’t realize could be connected. Rich stresses that you can’t do this at the computer, you need to go somewhere and have no external input. He recommends going somewhere you can close your eyes but not go to sleep so you can sort of switch your brain from external to internal input(all that information about your problem that you just reviewed).
The other substep is to leave the problem alone for a while and let your background mind do its thing. Sleep is a great way to do this, or going for a walk, or anything that gets your waking mind off of the problem. If you’re working on a hard problem you should sleep on it for at least one night, more if it’s a really hard problem. Just because you have an idea right away doesn’t mean you won’t have a better one in the morning. And once you have an idea, analyze it, don’t just run with it. Just because you slept on it doesn’t mean that solution that popped into your head in the morning is perfect.
Optional step 7: don’t stay stuck. If you have another problem to work on, do that when you feel stuck instead of just sitting there and staying stuck. If you don’t have another problem or really need to stay focused on your current one, gather more input, talk with more people if you can, and go through the whole process again.
A caveat to this whole process is that if you do have more than one problem you’re working on, you may spend hours loading up all the information about one problem and wake up the next morning with the answer to a different problem. That’s a thing you just have to accept, brains are funny sometimes. If you can’t switch to the other problem, at least write down the solution you came up with before going back into gathering information and loading it up for the problem you really want to solve.
Rich’s talk is really good and I highly recommend watching it yourself, but if you don’t have 40 minutes to dedicate to sitting in front of your computer then I hope this recap was helpful.
Today’s link is a companion to my earlier post with resume advice. After resumes come interviews, and in those you’ve got to ask your interviewer a few questions. When you’re just starting out it’s really hard to know what’s okay to ask or what you would even want to ask. Fortunately Jen Hamilton compiled a fantastic list of questions to ask interviewers from various sources (they’re linked at the bottom) and her own interests and experiences.
A couple of questions I’d like to highlight are these ones:
Flex time/core hours? Is variability tolerated or is everyone expected to be on the same schedule?
Is it possible to work from home, say, 1 or 2 days a week? Does anyone do this?
Just because a lot of companies that hire developers work normal 9-5 hours doesn’t mean they all do. I’ve heard enough horror stories to strongly recommend asking exactly when you are expected to be in the office/available online and whether it’s going to be a big deal to work from home to let the field tech in to fix your internet connection.
I was poking around in /r/javahelp, saw a question about something I haven’t personally done, and found what I strongly suspect was the answer right away. I try to explain how I found the answer when I answer questions like that because “oh it’s _____” isn’t really that helpful in the long term. I mean, what is the question asker supposed to do next time if I’m busy or sick or on vacation?
But how do you explain “well obviously that’s a_____ problem”? I can explain that I googled a thing and didn’t get very helpful results so I googled another thing and found what I needed, but not how I knew what to search for in the first place.
learning better perception skills such as differentiating two musical tones from one another or categorizations of spatial and temporal patterns relevant to real-world expertise as in reading, seeing relations among chess pieces, knowing whether or not an X-ray image shows a tumor.
After you’ve worked with enough code and seen enough different kinds of problems, you just kind of know what the answer is (or at least a few things it could be) when you see a new problem. And that, finally, is what being an experienced programmer really means. It’s not about some magical level of skill or about instantly knowing the perfect solution for every problem or even finally feeling like you know what you’re doing, it’s just about having seen enough problems that you end up with a library of them in your head.
I can’t tell you how long that will take but on the upside I can tell you it will definitely happen if you just keep coding. Okay, there are people with “ten years of experience” who really just have one year ten times, but if you care enough about programming to bother reading my blog, you’re not one of them.
Another part of being an experienced programmer is that once you feel confident about getting your code to do what you wanted, you sort of move up a level and start worrying about whether it’s a good idea to do it that way. That’s where people with one year of experience ten times really fall down, they can make things work but can’t make them maintainable. Getting to the point where you worry about the right way to do things takes a little more deliberate effort, but the most important step is just to care about whether it’s possible to change your code.
Once you’re past struggling to get your for loops to work and once you’re past feeling totally overwhelmed by starting a new project, it’s really tempting to think that you’re done, you’re a “real” programmer now and there’s nothing else you need to learn. But if you stop there, not only will you never be a very good programmer, but more importantly you’ll miss out on one of my favourite parts of programming, which is figuring out how to design things so you won’t curse your name in six months when you need to change them. For me that’s way more fun than Strings and Arrays.
All this is to say that if you’re a beginner programmer and you see a job posting looking for developers with x years of experience, all they really want is someone who can reliably get things to work (not necessarily immediately) and who knows a bad idea when they see one. If you can do that, go ahead and apply. It’s not unusual for job postings to be more of a wishlist than a list of what the job actually requires, anyway :)
Today’s tip is a very simple git feature that I always seem to forget. Maybe by putting it on my blog I’ll finally remember it exists!
git reset --hard origin/<branch name>
What this does is force your local branch to really for really real match the state of the remote branch. If somebody reverts a bad commit on a remote branch and your local repo insists your copy is a commit ahead of the remote no matter how many times you try a simple git reset, then that command up there is what you need to fix things.
The academic year is ending pretty soon and students are probably starting to look for co-op jobs, so hey, why not throw some unsolicited resume advice at people?
First a quick disclaimer, I help review resumes now and then but I don’t have a huge amount of experience with it. Some of the stuff I’m going to tell you is stuff I’m really sure I’m right about, and some of it is just my opinion.
My first piece of advice, and the one I’m the most sure about, is proofreading. Proofread your resume! Put it away for a little while (at least a few days), and proofread it again! Get a friend to proofread it! Get your parents to proofread it! Go to your school’s career center and get them to proofread it! Wow, the word proofread looks really weird when you use it that much :)
But seriously, proofread! Why am I harping on that one so much? Because a resume with mistakes on it shows you aren’t good at fiddly little details. That’s a serious problem because programming is fiddly little details. Compilers and IDEs and syntax highlighting text editors can help you catch a lot of bugs, but they can’t catch logic errors for you. To find and fix logic errors, you have to pay really close attention to the code and keep track of every little detail. If your resume has mistakes, that makes me very worried that you’re going to struggle with programming in general and logic errors in particular and honestly, that’s going to make me very likely to set your resume aside. I say “very likely” because it is possible that if you had some really great projects on your resume I would still consider your resume, but you know, it’s a lot easier just to proofread the hell out of your resume :)
On top of making me worried about your ability to program, having mistakes on your resume just looks sloppy. That’s really not the first impression you want to make on a potential employer. In school it’s not as big of a deal if you lose a couple of points for having a typo or an autocorrect fail, but when you’re applying for a job that’s very likely to take your resume out of consideration entirely.
My next piece of advice is detail. Almost no one has too much detail on their resume, you basically can’t go wrong if you add more detail about exactly what you did, especially on projects you did as part of a team. When I’m looking at a resume, I want to know what you did. If you were involved in every part of the project, just say that instead of letting me wonder what you actually did. If you just did, say, the back end part of the project, say that! If I’m looking for a back end dev, I want to know if you have back end experience.
This one’s a little more subjective, but personally objectives on resumes take up space that could be used to tell me something more interesting. I mean, I know you want to work on software, it would be pretty dumb to apply for a dev job (co-op or otherwise) if you didn’t. That said, I’ve heard from other people that objectives make it easier to keep track of which position someone is actually applying for, which can be really handy if you don’t use an applicant tracking system and have a pile of resumes you’ve printed out. Basically, go ahead and include an objective if you want to, but don’t feel that you have to just because your teacher said so.
Job history is a tough one for students especially, I have two pieces of advice for you there. One, it is totally okay to have a projects section on your resume if you don’t have a lot of relevant work experience. Heck, even if you do have a lot of relevant work experience, if you have projects you’re proud of have a project section on your resume! Opinions differ on this one, but I think it’s perfectly fine to include school projects on your resume. What else are you supposed to do if you’re a student?
Two, you do not have to list every crummy summer job you’ve ever had. Especially if you took breaks from school to work to pay for your next semester, you do not have to use up half a page listing every retail/hospitality/whatever job you’ve ever had. If you took breaks from school to work it’s not a bad idea to explain that in your cover letter, but I’d much rather hear about cool projects from your classes than about stint #4 at $FastFoodPlace on your resume.
Readers, do you have any advice for students or anyone who doesn’t have years of dev experience to put on their resumes?
Today’s link is a set of nifty Chrome dev tools tricks. I don’t know about you but I haven’t done much front end work lately, which means I keep forgetting that things like DOM breakpoints exist. Even if you work on front end code all the time, maybe you’ll find a useful tip in there too :)
The big tip for post #8 in the be a better programmer while still having a life series is to become a witch. A Terry Pratchett style witch, to be precise. Terry Pratchett’s witch characters are really great at two things: first sight and second thoughts. To quote him directly:
First Sight and Second Thoughts, that’s what a witch had to rely on: First Sight to see what’s really there, and Second Thoughts to watch the First Thoughts to check that they were thinking right.
Back at my original point, first sight is seeing what’s actually there, not what you wish was there or what you thought was there or what you meant to put there. Does that remind anyone else of debugging?
Fortunately for programmers, we have tools like debuggers and IDEs to help us see what’s actually there. We also have techniques like simply getting up and taking a walk, or explaining our problem to a rubber duck (or maybe another programmer if it’s a really hard problem), or commenting out half of our code and then half of that half and so on until we find the problem line. Let’s just not think about how much programming must have sucked in the days before friendly IDEs that highlight mistakes for you :)
Another part of first sight for programmers is also your attitude. If you don’t want to see the problem, you’re just not going to no matter how observant you are normally. I’m by no means perfect at it myself, but I’m convinced the most useful attitude you can bring to debugging is the simple acceptance that you got at least one thing wrong. The longer you spend insisting that your code should work, the longer it takes to figure out what’s actually wrong with it.
Moving on, second thoughts are thoughts about your thoughts. When you think you know the best way to build something, why do you think that? How do you know you’re right? Is that actually the best way or is it just the first way you thought of? How would you know either way? What constitutes the “best” way to do something? Is “best” the most performant, the easiest to read, the easiest to change, the quickest to write, the easiest to test? If “best” for your project meant quickest to write yesterday, does it still mean that today? How would you know when that changes?
Checking up on yourself like that is really hard to do and that’s why this post is more for me than for you – I’m trying to remind myself to question my assumptions.
One of the traps I fall into most often is looking for an example of what I want to do in our existing code and then assuming the first thing I find is the right way to do it. Shockingly enough, codebases change over time. Just because something worked well when it was written doesn’t mean nobody has thought of a better way since then or that the rest of the app hasn’t changed enough to make the old “right way” completely different from today’s “right way.” Just like you look for a couple of sources that agree with each other when you’re Googling what an error message means, look for a couple of examples in your codebase and if they’re different, check which one is newer.
Getting into the habit of thinking about how you think is not easy (at all!), but it’s useful and, like the other installments of this series, not something that you have to devote all of your free time to. It’s also useful in pretty much every area of your life. When you have any problem to solve, how do you know you’re right about how to solve it? For that matter, how do you know you’re right about what the problem is?
When I’m stressed out, every little thing drives me absolutely crazy. I can end up convinced that what’s bothering me is that this stupid freaking feature won’t work no matter what I do when the real problem is that I’m trying to hit a tight deadline and marketing keeps changing their minds about what’s important and half the QA team is sick so they need extra time to test everything and that means I need to deliver even sooner and everything is terrible!
Okay, so what do you do about that? For starters you really should read that blog post I linked earlier, Amy Hoy goes into a lot of detail about learning to notice yourself thinking. My big tip is just to get into the habit of asking yourself “Why? Why did I decide that? Why is that the best way? Why is that bothering me so much?” Sometimes the answer is going to be stupid simple: I decided to go to cafe at the front of my building for lunch because the weather was hideous and I didn’t want to go outside. Sometimes the answer will lead to more questions, like when you ask yourself “Why did I decide to put that config file in that directory?” In my case the answer was “Because that’s where the other config file lives” which leads to another question: “How do I know both config files should go in the same directory?” From there I learned all sorts of stuff about which files were supposed to go in the original directory and why, and where the other file that was related but not the same type of config ought to live.
This is the kind of thing that takes a lifetime to master, so don’t feel bad if you don’t get it right away. Asking yourself those questions is still worth it even if you only remember to do it sometimes.