You’re reading Signal v. Noise, a publication about the web by Basecamp since 1999. Happy !

Signal v. Noise: Programming

Our Most Recent Posts on Programming

Kicking the tires: My trial month

Nick
Nick wrote this on 28 comments

I saw some questions on David’s last posts about remote work and hiring asking how we evaluate potential employees. Racing metaphors aside, tossing new developers on real projects is a time honored tradition here, and one that we haven’t written yet about “what” exactly happens along with the “why”. Here’s how my trial month went, and what I learned.

Giordano's pizza and a pint of 312, can't get more Chicago than this meal.

The first week

I’ve never been to Chicago, outside of O’Hare airport. I have terrifying memories of that airport, so I was cautious to visit. I once left an a320 Pocket Retro Emulator in a seat pocket while deboarding, and didn’t realize it until soon before my connection was to leave. I sprinted back through 2 terminals to find the plane had already left for Nashville. I hope someone else is enjoying a slightly buggy version of Tetris Attack. My first week at 37signals went much better than this experience.

The first week in the office was great. Getting up to speed was a breeze: I fired Ruby and Rails up on a fresh box with rbenv and ruby-build. After cloning down a few repositories, and the usual run-around of “what passwords/sites do I need access to”, I was tossed into the fray of our support queue.

I was introduced to Assistly, which we use for customer support. I have to say, our support team is awesome to work with. We typically have 3 developers rotating in on-call, usually on a weekly or so basis. Here’s basically what on-call for a 37signals developer looks like:

  1. Support is stuck with an issue, and our set of internal tools isn’t helping.
  2. An issue is called out for developers to look at.
  3. Cue hacking montage as we dive into that specific product and various gems’ codebase to find the problem. This usually involves a trip into our server cluster to look for logs, find emails that didn’t process or hook up to a Rails console and hit the database.
  4. If it’s a bug, try to squash it. At least make sure we know about it in GitHub Issues.
  5. Ship it! Bug fixes and more are logged through Champagne, our internal change tracking tool. Champagne is in charge of publishing our Changes page.

Sometimes there’s not always an easy fix, or it’s a deeper issue. Typically we’ll discuss these over in Campfire to begin and see if anyone’s seen it before. This usually escalates into kicking off or contribute to ongoing discussion in Basecamp about how to solve the root problem.

Back to remote

On my first week back in Buffalo, I was tasked with creating a fresh application we’ve needed for a while. The workflow for discussing changes and features was pretty much what I expected: Here’s a list of things to accomplish, let’s see what we can get done in a week. The timeboxed aspect of the project was definitely new to me, and I think it was a great factor in focusing on what needed to get done instead of what could be done. I’m very new to a product-focused company, and this was a great way to be dropped into the environment where it’s really the customer and user experience that comes first and foremost.

After that second week remote, I went back to on-call. I really enjoy the balance of the on-call work. It’s usually split 50/50 between helping customers with issues blocking their work, and improving our infrastructure and apps. There’s lots of dirt to sweep up, including deep bugs that need investigating and apps/gems that need a fresh coat of Ruby or Rails.

Back in Buffalo, this is Bidwell Parkway.

Top score!

One thing I learned really quickly was that our users are creative: If you give them the ability to do anything, they will do everything! I found this out the hard way when we got a support issue for an extremely broken Basecamp page. After some investigation, I found out that Basecamp todos allow HTML tags, and they forgot to close one. After a fruitless hunt for why this behavior existed, I shipped a fix to strip out HTML tags and clean up ones that might cause the page to break.

The flood of support issues started almost immediately. Apparently a lot of users customize their todos with colors, images, and more. Suddenly, they couldn’t, and it was my fault. This might be a new personal top score for breaking things at a new job. I reverted the fix and deployed once again, and we apologized to those users.

Keep kickin’

I’m still getting used to remote work, but I’m enjoying the greater freedom and flexibility so far. The discipline of working near so many distractions is something I’ll be working on for a while.

This is my second official month being a signal, and I’m definitely still learning about our infrastructure and the internals of our products. I have to say though, it’s been a lot of fun and I’m excited for what’s next. If you have any other questions about the trial month experience let me know!

Why we don't hire programmers based on puzzles, API quizzes, math riddles, or other parlor tricks

David
David wrote this on 174 comments

I remember the first time I interviewed for a front-end programming position and got asked how to do something in JavaScript on a white board. The specifics are vague, but it’s crystal clear how stupid it made me feel and how little it had to do with the actual job.

Since then I’ve rarely heard a kind word about the parlor tricks of programmer hiring, but I’ve heard plenty of scorn. There’s certainly a minority of puzzle solvers who love to get their fancy tickled like this, but I sure wasn’t one of them and neither have most programmers I’ve met.

I’ve known fabulous programmers flame out in the quizzing cage and terrible ones excel. So unless you’re specifically hiring someone to design you the next sorting algorithm, making them do so on the white board is a poor gauge of future success.

The only reliable gauge I’ve found for future programmer success is looking at real code they’ve written, talking through bigger picture issues, and, if all that is swell, trying them out for size.

(If you need help posting a comment, feel free to use any of these samples: “You make todo lists, you don’t need real software engineers”, “Math is actually really important, you know!”, “Google is worth one gajillion dollars and they use quizzes, so there!”)

Top-tier this

David
David wrote this on 96 comments

If I hear one more Silicon Valley type gush over a computer science graduate from CMU, MIT, or Stanford, I’m going to puke. Yes, yes, I’m sure these are mighty dandy nice schools, but you’re letting the stench of superiority and shallow whiff of superficial judgement pollute my airways.

The fantastic thing about programmers is that we don’t have to give a fuck about where they were trained because we have something much better available: We can look at what they actually do! We don’t need the indirection of pedigree to guess at their skills, we can look at their code and know it.

Here’s a list of the top tier schools that helped shape the fine band of programmers we employ at 37signals:

  • Lawrence University
  • Rochester Institute of Technology
  • Brock University
  • Washtenaw Community College
  • California Institute of Technology
  • Copenhagen Business School
  • Brigham Young University

Remember, a real engineer doesn’t want just a religion about how to solve the problem. Like ‘object-oriented’, or ‘functional’, or ‘imperative’, or ‘logic programming’. This piece of the problem wants to be a functional program. This piece of the program wants to be imperative. This piece wants to be object-oriented and guess what—this piece want to be logic-based. And they all want to work together usefully, because of the way the problem is structured.


Gerald Jay Sussman, We Really Don’t Know How to Compute!

Why programs become territorial

David
David wrote this on 35 comments

“Can you ask Sam about that? Stacker is his domain”, “I’d rather let Josh look at the router, he wrote it”, “Jon is better versed in associations, send it to him”.

The natural progression of programs is towards the territorial. When a programmer has weaved an intricate web of considerable complexity, others are loathe to enter his lair and he is loathe for them to do so.

This is despite the fact that we all agree that it’s bad for programs to become territorial. When only one or a few people know how to work on something, you get bottlenecks where progress is stunted until the master is ready. You risk the hit-by-a-bus factor where nobody knows how the system works if the master leaves. You ensure the annoyance of stakeholders who can’t understand why another minion can’t fix his urgent problem.

But this problem can’t be solved with a slogan. You can proclaim that “we shouldn’t have territorial parts of our program” until you turn blue, but nothing is going to change until you accept the cost of avoidance.

The first step of acceptance is to recognize that sending someone fresh in to fix a single issue in a complex part of the code is expensive. It’s going to take Pratik five to ten times the effort to fix a single issue in Stacker that it’s going to take Sam. And the odds are that even that is not enough to appreciate the internal coherency of the system, which means that the fix is likely to be a butcher’s job, and Sam will have to rewrite it afterwards anyway.

To broaden the base of knowledge, you’re going to have to let someone else not only spend considerable effort getting up to speed. Then you’re going to have them deal with more than just a quick fix. Let them deal with a raft of issues and let them spend the time of the original creator to learn it all.

To do all that, they can’t do anything else at the same time. That feature you want do is now going to be pushed a few days or a a week out. Until you’re ready to delay things you really want done, it’s fruitless to bemoan that parts of the code base territorial.

Four tips for learning how to program

Jamis
Jamis wrote this on 39 comments

I recently received an email from someone who was getting into programming, and was asking for advice on how to proceed. He had a project in mind, and had started on it, but had run into areas where his current knowledge was insufficient to puzzle out the solution.

First of all, I was very impressed that he had actually started work. Ideas are a dime-a-dozen, and one of my least favorite things are “idea people” who feel like their work is done when they come up with an idea, and all that’s left is to find a programmer who is willing to fill in the blanks. That this person came to me after first trying to solve it himself was a huge mark in his favor.

Sadly, I wasn’t able to help him take his project further, but it gave me a chance to think back on the times that I’ve been a beginner (whether it was web programming, or iOS programming, or even something unrelated to software entirely), and to contemplate how I approached those beginnings.

I identified four things that I’ve found were fundamental to my particular learning style. Obviously, there are as many learning styles as their are learners, but these are what work for me.

Continued…

Setting up a new machine for Ruby development

David
David wrote this on 33 comments

It used to be a jarring experience to setup a new machine for development, but progress has paved the dirt road into a silky smooth autobahn. These are the tools we use today:

  1. Homebrew: Remember how painful it used to be to get imagemagick installed? Now it takes about a minute. “brew install imagemagick”. Same story for git and other Linux dependencies.
  2. rbenv/ruby-build: We have some apps running on Ruby 1.8.7, some on 1.9.2, and some on 1.9.3. ruby-build makes it easy to compile all three, rbenv makes it easy to switch between them on a per-project basis. We run rbenv in production as well, so all you need to do to change the Ruby version there is alter .rbenv-version—development and production is always on the same page.
  3. Bundler: Not everyone at 37signals loved Bundler at first, but now that it’s stable, they’ve been won over. I now curse whenever I have to use an old application that hasn’t been setup with Bundler. Manually tracing down dependencies?! How prehistoric!
  4. rake setup: All our apps has a rake setup task that’ll run bundler, create the databases, import seeds, and install any auxiliary software (little these days) or do any other setup. So when you git clone a new app, you know that “rake setup” will take care of you.
  5. Pow: No more messing with Apache or nginx for local development. All it takes for Pow to add another app is a symlink. All the apps are always configured and available at basecamp.dev, highrise.dev, etc without messing with the hosts file either.

Thanks to Max Howell for Homebrew, Sam Stephenson for rbenv/ruby-build and Pow, and Carl Lerche/Yehuda Katz for Bundler. Thanks to them, starting from scratch has never been easier.

CSS tip: Spot unsized images during development

Sam Stephenson
Sam Stephenson wrote this on 31 comments

Have you noticed that software feels cheap when UI elements move around on the screen without notice? Web applications are particularly vulnerable to this problem. Browsers give image elements a default size if they do not have explicit width and height attributes. Once these images have loaded, they expand or contract to their full size, causing all other elements on the page to reflow in response.


Unsized images reflow the page when they load

We try to avoid this in our applications, but it’s easy for an image tag to slip through the cracks. That single tag might be repeated many times in a loop, each instance causing the on-screen furniture to shift around in an unseemly way.

Here’s a tip for catching unsized images during development. Add this CSS rule somewhere in your stylesheet:

img:not([width]):not([height]) {
  border: 2px solid red !important;
}

Then any images without width and height attributes will be drawn with a red border so they’re easy to spot.

Sam talks Javascript on The Changelog

Ryan
Ryan wrote this on 2 comments

The Changelog posted a podcast interview with our very own Sam Stephenson. He talks about CoffeeScript, the Rails 3.1 asset pipeline, open source projects Pow and Sprockets, and the development of Basecamp Mobile.

The key difference to me is that when I look at a piece of Javascript code, I see parentheses and braces and semicolons and line noise. And when I look at CoffeeScript, I can see the code that I’ve written.

When I’m writing CoffeeScript I’m still thinking in Javascript—I just have to type less.

One of my favorite things is the ending: the interviewers ask “Who do you look up to?” That’s a great question to ask anyone who is doing good work.