Communicating Salary in Job Postings

This is part of my continuing series on applying Jobs-To-Be-Done product design theory to the problem of recruiting. In my first installment, I explained the concept and gave some idea of applying JTBD to recruiting would mean:

In their workshops, Bob and Chris teach how to find out why people switch from one product to another by interviewing people that have done it already. How many of us have interviewed our recent hires to find out why they switched from their old job to ours, how they found out about it, what happened in their lives to cause them to want to switch jobs? If we did that, I think we’d find that we’re advertising in the wrong places, not emphasizing the right strengths, and generally not making the applicants know that we meet their hiring criteria.

Next, I wrote about the problem of hiring passively looking developers, where the key question I addressed was: “What would you do to your recruiting efforts if you wanted to hire people that aren’t looking for a job?”

Following along that vein, and again, using JTBD techniques, let’s talk about “progress making”. Essentially, people switch (products, jobs, houses, etc) because they are trying to make progress in their lives. In order to design products that make people switch to them, we need to know what kind of progress our users are trying to make.

In this case, it’s pretty uncontroversial to say that our potential applicants are looking to make progress in their compensation, or, if they are willing to trade that against other things, they have a lower limit.

Salary, for a potential job switcher, hits all of the forces of progress making.

  • They are pushed toward switching by the feeling that their current job doesn’t value them enough;
  • they are pulled toward switching by a job that pays more;
  • they are pulled back from switching by familiarity with their current pay structure and raise schedule;
  • they are pushed away from switching by anxiety that other jobs won’t pay as well (or have less potential for future salary growth).

Dissatisfaction, aspiration, allegiance, and anxiety: to get someone to switch we need to address all of these, and increase the first two while lowering the other two. (learn more about the forces from JTBD Radio).

Our potential applicants have total knowledge of their current salary, so to help people realize they will make progress, they need to know what we are offering. For the passive looker, who is not willing to invest much in each opportunity, the risk of early filtering is high. The unknown feeds the anxiety component and does nothing to drive aspiration (the two forces our offer directly controls), so they won’t associate “progress making” with your job description.

[ASIDE: I know why we don’t list salary in job postings, but I would say that whatever those reasons are need to be balanced against wanting to make our job attractive to top developers, which we believe are not actively looking for a job. So, if we accomplish “having a good starting point for negotiation”, but not “attract top developers to applying for our job”, we failed.]

To alleviate anxiety about your offer, I would try social proof, a lossy communication channel, or possibly a transparent salary ladder.

For social proof, get candidates via referrals from your employees. People will make a judgement about your salary scale based on what they know about their contact.

By lossy communication channel, I mean a way to communicate salary possibilities such that the candidate gets an idea, but knows that it might be wrong and doesn’t interpret it as an offer. One way to do this is with a 3rd party recruiter — you give them a range, and they will leak it to the applicant, who will have skepticism for anything a recruiter tells them. You could try 3rd party ads that “estimate” a salary or write up truthful descriptions in something like GlassDoor or other salary reporting places.  No one thinks those are definite, but at this point, they just need some idea.

A third option is to have total transparency and a completely non-negotiable salary ladder. This is what union and government jobs do (so it has a bad rap), but I’ve seen tech companies try it — here’s a really old post from Joel Spolsky about Fog Creek’s compensation and here’s a very recent article about Buffer’s compensation policy. Both use a formula based on mostly objective criteria.

Your goal is to throw something out there to alleviate anxiety enough to get them to contact you.


You rarely see an ad that is so good that it would be missed if it was removed. It’s not easy, but if you want to shake things up a little, look at one of the publications you advertise in and think about what it’s missing, then buy space and add it.

My favorite example of this is the PC-Lint “Bug of the Month” ads that ran in Dr. Dobbs and C++ Report. These were essentially the puzzle section of these magazines, and I used to spend time engaging with the ad each month. Solving the puzzle gave you a visceral understanding of what the product did.

You have to be careful. The other way you see this tactic being used is to make fake content that tries to trick the reader into thinking they are reading another article. I never think it’s a good idea to start off a relationship with such a blatant lie.

The better way is to be clearly an ad, but still have compelling content.

Some ideas

  1. Puzzles, like PC-Lint did. The trick here is that solving the puzzle should be a little like using the product. Just putting a Sudoku in your ad space probably isn’t going to cut it.
  2. Comics. For example: SourceGear ran a serial comic a few years ago.
  3. Pure educational content — don’t make it look like the publication, instead make it the text of your first auto-responder. It should deliver value
  4. Information. I’d look to Kinvey’s Backend-as-a-Service ecosystem map — I don’t know if they advertise it, but if they did, I would probably tear it out. If it was updated more often, I’d eagerly await the magazine it was in to get an updated copy.

The key is that it should add value to the content it’s delivered in. Hence: the addvertisement.

No Pixel Left Behind

I’ve been running iOS7 for a few weeks now as I refresh the look of my apps.  Habits is kind of getting there, but I’m trying to internalize the design lessons of iOS7.  Basically, my mantra is, “no pixel left behind”, which means

  1. If I can change the color of a pixel with no loss of semantic meaning, make it the background color
  2. If I can add meaning with space and grouping, do it, and remove more pixels
  3. If I can add meaning with color, do it
  4. It’s ok to have “brand” colors, but use them only when you need contrast

Here are some other lessons

  1. Prefer to reveal more UI rather than navigate
  2. Make gestures feel like they are moving a physical object (e.g. use pan instead of swipe)
  3. Prefer fewer words, but use enough to not be distracting

Habits 2.02 should be ready in a week with these lessons applied.

The 0-Liner

If you want to show off the power of your programming language, nothing works better than a cool one-liner (or even better, a code tweet).

I have to program in a few different languages, of varying degrees of power, and one thing you start to notice is the 0-liners — the code that just doesn’t exist.

An obvious example is how garbage collection (or ARC) gets rid of memory management. Here are a few more examples:

In Objective-C, nil sinks messages. This means that in a lot of cases, you don’t have to check for nil and “the right thing” happens automatically.  If you send nil a message, it’s a no-op, and if you need a return, you get 0 for scalars, nil for objects, 0-filled structs, and undefined for anything else. You still consider the nil case, but you usually don’t need to write any code.

This is a real example of a language completely implementing a design-pattern, in this case Null-Object. You can get similar behavior by using this pattern. Clojure does even better by letting you implement a protocol on nil to provide implementations for its functions called with nil. But, neither of those are 0-liners.

I don’t use F# (or Scala), but my understanding is that when Some/None discriminated unions are used in computation expressions, the computation will end and return None if some part of the expression returns None.  This is a classic 0-liner, if I’m right.

async in C#/F# (and go blocks in clojure’s core.async and go) rewrite sequential looking code to actually be asynchronous with callbacks.  Miguel de Icaza covered this recently in his post, Callbacks as our Generation’s Go To Statement.

Just like in the Go To days, or the days of manual memory management, we are turning into glorified accountants. Check every code path for the proper state to be properly reset, updated, disposed, released.

In this case, only go and clojure are true 0-liners, as you still need the await keyword in C# (and let! etc in F#) to indicate a blocking call.

clojure’s BigInt contagiousness turns your overflow checks into 0-liners. If this is a possibility in your integer algorithms, it’s worse than null checks.

What’s your favorite 0-liner? The nice thing about them is that they don’t use up any of your 140 characters in a tweet.

Recruiting Passively Looking Developers

This is the second in my series at applying Jobs-to-be-done (JTBD) techniques to Recruiting. To recap, our open job position is hired by applicants (gets a job done in their lives) and has hiring criteria that the applicant applies when making decisions about it.

In their JTBD training, Bob Moesta and Chris Spiek teach how to interview to understand the JTBD Timeline (here’s a great description of the JTBD Timeline from Ross Belmont and here’s Bob and Chris’s JTBD Timeline Diagram). In this post I want to concentrate on the beginning of the timeline — the part where someone has the first thought that they might switch and up until active looking.

I believe that that the vast majority of excellent software developers are not actively looking for a job. Back in 2007, Joel Spolsky put it this way:

From a recruiting perspective, the problem is that the people I consider to be in the top 1 percent in my field barely ever apply for jobs at all. That’s because they already have jobs. Stimulating jobs. Jobs where their employers pay them lots of money and do whatever it takes to keep them happy. If these pros switch jobs, chances are the offer came through networking, not because they submitted a resumé somewhere or trolled a job site like Monster. Many of the best developers I know took a summer internship on a whim and then stayed on. They have applied for only one or two jobs in their lives.

If you want to run a world class development team you need to internalize this. What would you do to your recruiting efforts if you wanted to hire people that aren’t looking for a job?

Here are a bunch of things that won’t work at all

  1. Advertising on job sites
  2. Tweaking your “Company > Careers” page
  3. Hiring headhunters (despite the hunter name, they are usually gatherers)
  4. Tweeting, Updating Linked-in statuses, etc.

It’s fine to do these things — there are actually active job-seekers. But, if you look at typical recruiting, this pretty much sums up the entire effort.

Also, targeting the passive lookers is a long-game. If you need someone right now, then traditional recruiting is your best bet. But, in the long run, if you know you need a steady stream of applicants to succeed, you have to have a plan to target passive lookers.

Here are some examples of what others do;

  1. In the link above, Joel’s solution is an internship program. Not just any one — he treats it like the critically important company building tool it is:

    I send a personalized letter to every promising computer science major that I can find. Last year I sent 300 letters to fill six intern positions. Not e-mail. My letters are printed on a real piece of Fog Creek letterhead, which I sign myself in actual ink. Apparently this is rare enough that it gets kids’ attention.

  2. Matasano Security is “always hiring security consultants. Really.” In order to help build a pipeline of passive developers who know they exist and what they do (and that they are hiring), they have a “Crypto Challenge” email campaign. When you sign up, they email you list of crypto coding puzzles. They don’t recruit through this e-mail, but if know Matasano at all, you know that they are always hiring.
  3. I work in developer tools, so I know that our marketing department is always talking to developers (hey, we’re hiring a Developer Evangelist to help us do that even better). If you market to developers, you should have a plan for making sure they know how great it would be to work for you. If you don’t, but you need to hire a lot of developers, adding an SDK product to your line-up is not a bad idea (it’s probably a good idea anyway — the software business is all about platform proliferation).
  4. You absolutely need to have a functioning referral program — almost everybody has something, but if you aren’t getting a significant number of leads this way, you need to be having a tough conversation with your developers about why they wouldn’t recommend that others work with them. The answer is NOT that the referral program doesn’t pay enough, but you could probably make it work if you overpay.

I believe that #4 is your indicator that you have solved the JTBD for recruiting (which is that the product is right — your developers love their job and would recommend that others with them). Look at the end of the timeline I linked at the beginning of this post — it ends with satisfaction (or not), and the point of that is repeat business and word-of-mouth.

Habits 2.01 – Start Small

When I announced Habits 2.0, a fellow Western MA Hackathoner, Molly McLeod, reminded me of BJ Fogg and his Tiny Habits method.

Only three things will change behavior in the long term.

Option A. Have an epiphany
Option B. Change your environment (what surrounds you)
Option C. Take baby steps

I had first learned of BJ from Ramit Sethi’s interview with him. The moment I remember most clearly was his method to start to floss. He suggested that you only commit to flossing one tooth each day — if you did that to start and internalized that that was success, you’d start flossing more eventually. I started doing this, and while I’m not a perfect flosser, I do floss most of the time. That convinced me that baby steps were a real thing. If you have any interest in this, sign up for a (free) week-long tiny habits session with BJ.

So, with Habits 2.0 out the door, I am going to plan 2.01, a baby step improvement of 2.0 by just doing a very small amount of work each day on it.  I joined BJ’s tiny habits for this week and he recommends adding a 30-second behavior triggered by something you will definitely do each day. I decided that once I put my dinner plate in the dishwasher, I will sit at my desk and run the Simulator. Then, I will celebrate that as a success (and mark it done in Habits, of course).

I have been doing that for about 6 days, and each day when I run the simulator, I usually test Habits out a little, and write up a Trello card or write a small test.  BJ’s advice is to keep it completely pain-free and small and to not worry about building on the tiny behavior. Still, in this time I have managed to make a bunch of small improvements to Habits, which I look forward to sharing soon.

Four interesting tech jobs in the Pioneer Valley

I’ve been doing some research on how people advertise tech jobs, and I found a few interesting jobs in the Pioneer Valley that I want to share

  1. Fiksu: This company has offices in Boston and Northampton (right in downtown), and has an opening for a Software Developer in the Northampton Office.

    Fiksu, Inc. is a progressive, creative, fast growing, cutting edge
    advertising technology company for mobile applications.  We build the
    leading user acquisition platform to help brands achieve their
    business goals faster and more efficiently than ever before.

    Fiksu is looking for talented developers with a deep interest in big data, distributed systems, high scalability, open source technologies, and cloud computing.  You might not have much experience, but you’re a disciplined software engineer who is excited to learn and use new technologies and methods.

  2. Communicate Health: This company is right down the block from my house — I pass it every day. I met their Senior Designer, Molly McLeod, at the Western MA Hackathon, and she posted this job recently:

    Senior Web Developer
    CommunicateHealth, Inc. is a health education and communication firm specializing in improving health literacy through user-centered design, policy, research, and content development. At CommunicateHealth, we believe people deserve clear information about their health. This doesn’t mean using short words and lots of pictures — it means making sure the information and services our clients provide can be accessed, understood, and used by the people who need them most.

    The senior web developer will take the lead on many projects as our primary technical staff member.

  3. HitPoint Studios: The CEO, Aaron St. John, wrote to tell me about this position in their Amherst office.

    Windows 8 XAML/C# Engineer
    HitPoint Studios is looking for an experienced engineer to work on the development of engaging front-end user interfaces for Windows Store and Windows 7 games. We are seeking someone with one or more years of experience with WPF/XAML, familiarity with Windows 8 development (Windows Store apps for Windows 8 and Windows Phone 8), a strong background in MVVM design patterns, and a good eye for UI and UX design. The position involves maintaining and improving an existing reusable code base for multiple Windows Store and Windows 7 titles with similar front end functionality but varying UI views and feature sets.

  4. Atalasoft: Atalasoft publishes developer tools for imaging and capture applications. We have a great job for a web developer that wants to spend time helping software developers get to know our company and products better. It’s in the marketing department, and you’ll be creating technical content (demos, sample code, blogs, tutorials, copy for brochures, newletters, e-learning, etc) that we can use to reach developers and get them interested in our company’s products.

Apply Jobs-to-be-Done (JTBD) to Recruiting

Jobs-to-be-done (JTBD) is a theory for what causes us to buy things. The quick description is: jobs arise in our lives and then we hire products or services to do them. The key insight is that the job attributes should be used to guide product development, not the customer attributes. Here is Clay Christensen describing the concept if you haven’t heard it before.

[youtube_sc url=”″ start=”1520″]

This theory was publicly introduced in his book, The Innovator’s Solution, but is being popularized by Bob Moesta and Chris Spiek in Switch Workshops and soon at the Business of Software conference.

I was lucky enough to participate in some training with Bob and Chris, and so I often think of Jobs theory whenever I wonder why people do anything, and recently I’ve been thinking about recruiting (yes, Atalasoft has a job opening for a software developer in our marketing department to help evangelize our products).

Now, when hiring we naturally think of the job we need done, and of course, we are explicit about that when writing the ad, evaluating resumes, interviewing, ultimately hiring someone. The job has hiring criteria and we use it.

But, at the same time, potential applicants also have a job-to-be-done in their lives, and they are judging us with hiring criteria. In this case, we usually fall all apart. We try to write job descriptions that sell ourselves too, but, frankly, I’m not sure they actually address the applicant’s criteria.

In their workshops, Bob and Chris teach how to find out why people switch from one product to another by interviewing people that have done it already. How many of us have interviewed our recent hires to find out why they switched from their old job to ours, how they found out about it, what happened in their lives to cause them to want to switch jobs? If we did that, I think we’d find that we’re advertising in the wrong places, not emphasizing the right strengths, and generally not making the applicants know that we meet their hiring criteria.

I’m sorry to say that I haven’t done this, so I don’t really know what needs to change.

In any case, I’m going to be thinking and posting more about this — hopefully trying it in practice. In the meantime, if you are a web programmer (preferably in .NET or Java), have at least 5 years of experience, and you want to work in a developer tools company’s marketing department, creating technical content (demos, blogs, articles, sample code, tutorials, brochures, etc) to help developers learn more about our products, get in touch with me. At Atalasoft, you’ll work with smart and hard-working colleagues, where we have an enormous amount of respect and trust in each other. Some of the best programmers in Western MA have chosen to work here, and we can’t wait to meet you.


Habits 2.0

Back in 2008, I made a simple iPhone app called Habits to help me remember to do some recurring tasks that were not a regular schedule. I made a few updates early on, but it basically did what I needed it to do, so it’s been a while since I have looked at it.

Habits App IconA couple of weeks ago, I decided to refresh its look in anticipation of iOS 7. Unfortunately, an app compiled with iOS 6 doesn’t automatically pick up the new look — at the very least, you need to recompile. Instead, I decided to design something custom that would look good now and feel at home on iOS 7. While I was at it, I updated the icon using the iOS 7 app icon grid.

You can see some screen shots on the Habits documentation page, and if you want to buy it, Habits is 99 cents on the App Store.

Here’s a full list of everything that I had to do for 2.0 in case you’re a developer with an older app and want to see what you might be in for.

  • Converted to an ARC app
  • Moved lots of properties to auto-synthesize
  • Updated deprecated APIs to iOS 6.0 versions
  • Skinned the tables, mostly with custom cells
  • Added a pan gesture to the front-page cells (try moving them to the left for a short-cut)
  • Supported local notifications and badges (requiring a new settings page)
  • Made a new icon
  • Updated my Google Toolkit unit testing to Xcode built-in unit testing (which was gratefully, very easy) — the main issue is dealing with unit-testing’s idea of the document folder
  • Updated all button and default images
  • Updated in-app help
  • Converted my svn repository to git
  • Added database migration to support the settings (this app uses sqlite API directly)
  • Refactored a lot of code, mostly in the database, view controllers and custom cells, to share more code.
  • Fixed a bug in the calendar to support iPhone 5 size better.
  • Updated App Store listing, web page, made this post, etc.

Don’t assume ARC solves all of your memory problems

You should absolutely be using ARC in your iOS projects, and if the project predates ARC, go ahead and use the refactoring tool to get it to ARC. It really doesn’t take long and you’ll end up with a more stable app that will be easier to maintain.

That being said, you can’t completely ignore memory management. You can still get EXC_BAD_ACCESS, Zombies, leaks, etc., even with ARC projects. Here are some things you should know

  1. ARC is not garbage collection. It statically analyzes your code and then puts in release and retain calls where they are needed. It’s still susceptible to a retain-cycle — two objects with references to each other. You can still have references to dead objects.
  2. If you have a retain-cycle, a common way to deal with that is to make one of the properties weak (which you should probably do), but now that reference is susceptible to becoming a Zombie. A weak property will not call retain on the object, so when the object is deallocated, it would then refer to a dead object. If you have weak properties and get EXC_BAD_ACCESS, go reproduce it under the Zombie instrument.
  3. Under ARC, you cannot use autorelease any more, but the calls into non-ARC libraries can (and do, especially iOS frameworks). This means that you sometimes need to use your own autorelease pool. Under ARC, use the @autoreleasepool keyword to wrap areas where autoreleased objects are created that you need released before you return back to the thread’s main pool.  If you see leaks of objects in Instruments that you don’t alloc or hold onto, and use threads, add in @autoreleasepool blocks.
  4. Don’t use non-ARC code in your project by copying the source in. Build them in their own Xcode projects and then use the resulting .framework or .a in your project. It’s likely you wouldn’t be able to anyway, but just in case. (if you happen to be MRC — then really don’t copy ARC source into your projects — this will usually be compilable code, but will leak like crazy)
  5. Test your code under the Zombie and Leaks instruments — especially if you use bridging, weak references, or are in any way managing retain-cycles (breaking them yourself without weak).
  6. It’s rare, but I ran into a bug in the iOS framework that didn’t retain Storyboard created Gestures correctly in a tabbed-app. It was my first big ARC project, and it didn’t even occur to me to check for Zombies, but that would have pin-pointed the issue right away. Rule of thumb, the underlying code is still normal retain/release/autorelease based — debug it the same way you would have with Manual Reference Counting.

Further Reading:

Get iPhone programming tips in your inbox with my Beginner iPhone Programming Tips newsletter.