Category Archives: Software Jobs

Noticing Opportunities Using an AI Agent

I believe that Randomness is the Great Creator, which means that, to me, the universe is a random, unknowable thing that will offer us infinite variety. We can know our intentions, our goals, our wishes and pattern match the randomness against what we need. Some call this manifesting, but I think of it more like exposure and noticing.

It’s a way of taking advantage of the Baader–Meinhof phenomenon.

[which] is a cognitive bias in which, after noticing something for the first time, there is a tendency to notice it more often, leading someone to believe that it has an increased frequency of occurrence.

You don’t need to make opportunities happen more often if you can learn to notice them. So, tune this bias to things you want to notice. If you tell others your intentions they will be tuned on your behalf and think of you.

When I do this, I also enlist “AI” agents.

In 2005, I decided to look for a new job. I was in a non-profit, writing software for the organization itself. I had already realized that the better tech jobs were in product companies where the work I do drives revenue, so I set out to look for one.

I found sites that pulled jobs from many sources, but critically, could take a search term and use it to email me job openings on a regular basis. I set up a dozen search terms based on my personal job statement. I got weekly emails, each with a few jobs to check. It took a year, but eventually, I found Atalasoft, which was perfect for me.

This way of searching had the two elements I mentioned

  1. I had a specific intention
  2. I expressed it to an agent that would do its best to notice opportunities for me

I had always thought that finding my next job was blind luck, but I don’t think it was. I think I went through these motions less consciously.

I left Atalasoft in 2013 to do consulting. In mid-2014, I had decided that my next career move had to have some sort of optionality associated with it (little cost, but unlimited upside), so probably a startup. But I was deep in a project and not looking at all.

It was a confluence of several events in a short time that led me to apply to FogCreek and ultimately get a job at Trello. I was not looking for a job, but I was advising my client on remote tech recruiting/working, so I happened to be doing a lot of research on existing companies and saw the FogCreek ad on StackOverflow.

In this case, the StackOverflow job recommender “AI” made this happen. My activity and searches were training it to send me opportunities like this. I keep calling these agents “AI”s, but they were really just glorified SQL statements. Still, even that can be effective if you have enough data.

StackOverflow would have a deep understanding of my skills and my job history (I filled out their Developer Story and connected it to LinkedIn). Even though I had set my status to “not interested in opportunities”, I was doing a lot of job searches, many of them from my client’s office in NYC and some from my home in Massachusetts.

Similarly, FogCreek could train the AI to target developers like me. I had a high reputation on the site in tags that they might be interested in. I was senior and interested in remote work, but had lots of ties to NYC (and spent a lot of time there).

So, I had an intention, and I did express it to an agent, even if I wasn’t fully aware of this until years later.

The Unreasonable Effectiveness of Mathematics in Programming

(with apologies to Eugene Wigner)

My college didn’t have a CS major, but they let me put together one under a general engineering program. To fill up the requirements, I had to take a lot of math, which has been more useful than I expected a programmer.

I didn’t seek out jobs that required a lot of math. I optimized my job search around small companies doing product development for B2B, and didn’t care much about the specific technology they used. But, I was comfortable with the math, so it made my life easier.

The first eight years of my career was in FinTech, and the software I wrote was a nice UI around a lot of math. The core concept was options pricing (probability and statistics) and the sensitivity of that price to its inputs (calculus and differential equations). To do risk analysis, you have to build up huge matrices (linear algebra) for various purposes. Our company employed mathematicians, so we didn’t do the research, but we had to understand it to work on those parts.

Later, I contributed to a patent related to spreadsheets where graph theory was important. I also implemented numerical differentiation and root-finding algorithms for it as a way to run expressions backwards (numerical analysis and calculus). That patent expired, so I am reimplementing it in Swift and Typescript.

In 2005, I did a consulting project to implement a distributed monte-carlo engine for a decision support system. I would not have won this bid if I did not understand the math behind the engine.

From 2006-2013, I worked at an image processing tools vendor. This job was the closest to pure CS that I have had, and there was a lot of math, specifically linear algebra, but also some numerical analysis.

Every front-end position I have had uses at least a little linear algebra (for affine transformation). It’s not like you are doing the matrix multiplication yourself, but you’ll understand the more complex compositions better if you understand them. For example, if you know that matrix multiplication is not communicative, you’ll get why the order of the transformations matters.

Nearly every programming job now requires you to understand the analytics data that the software generates and to do statistical analysis on it. Forming a hypothesis and getting evidence to support or reject it is essential. At a bigger company, you might have a data-science team to do the heavy lifting, but it really helps if you can do it yourself—you also want to be able to read and understand their reports.

If you really want to go deep into the type theory behind type-safe languages (like Swift or Typescript), you have to understand set theory and maybe even HoTT. You don’t need it to use these languages, but if you had interest in compiler theory or implementing a language like this, it would help. Understanding set theory also helps with understanding relational databases.

When I was trying to find a Swift implementation of numpy a few years ago, I ended up finding Surge and contributed Eigen decomposition to it. I had to relearn it, but I would not have even tried if I hadn’t touched linear algebra since college.

Games are essentially physics simulators, which are ultimately math engines. I only write simple games as a hobby, but even for pong, I had to write vector math functions.

And, although I think my career has used a somewhat typical amount of math, there are programming jobs that require a lot of math. A deep neural network’s guts are a calculus and linear algebra engine (see this video from 3blue1brown). As I mentioned, data science makes heavy use of probability and statistics. I learned in Quantum Country that the “programming language” of a quantum computer is based on matrix multiplication with complex number entries. And while writing a game is a reasonable amount of math, writing a game engine is much more than that—and as more things (the blockchain, games, machine learning) have used the GPU for computing, the way you think of implementing solutions in those domains is more mathematical.

To be clear, you can do a lot of programming without understanding any of the math behind it. But, I have found it more enjoyable to go a little deeper, and it makes it easier to develop intuition about the higher level concepts.

In (weak) Defense of Algorithmic Tech Interviews

Yesterday, I wrote about my preference for work simulation tech interviews. There was one place I worked where we did more algorithmic tech interviews. Here’s why

  1. We were hiring almost exclusively people that had just graduated from a CS program. They were actually pretty good at these kinds of questions and didn’t really know much else we could ask them.
  2. The company made an image processing toolkit. There was a lot of data-structure and algorithmic code. There were a lot of optimization tasks. You really did need to know big-O for your code because all images had millions of pixels.
  3. All of our code was in C# and basically no one knew that already. So we hired people that could program in any language and needed questions that worked for anything.

So, the questions I asked were not too far removed from the kinds of problems we did need to solve, but they were technically algorithm/data-structure questions. At that job, with that codebase and with the strategy to hire new CS grads, I would do the same thing.

How to do a Work Simulation Tech Interview

I have written about how tech interviews are too much like auditions.

If you want to be in an orchestra, you need to audition. That makes sense because an audition is close to what the job actually is—a performance. This also makes sense for actors, comedians, dancers, etc.

A typical tech job is not a performance. For one, there is no audience. And, unlike a performance, we make tons of small mistakes and corrections along the way. Imagine a band performing a song like we usually program—it’d be a mess and not very entertaining (or very entertaining if you think of it as avant-garde).

But, I do think there is value in seeing a candidate actually do the job you are hiring them to do, so what I have tried to do is to simulate work as much as possible.

Here is what I recommend:

  • Describe it as pair programming. Unlike performances, this is something programmers actually do. Tell them that they are driving, and that you will be a helpful pair. This means that if you correct something, that that isn’t bad—it’s expected. You should correct things you don’t care about (and let them find the things that you do care about). Set up an expectation that mistakes are are ok.
  • Start with working code, not a blank slate. Send them a small working project that is like your actual code. For me, that was a working iOS app with one screen (all code was in one file). Run the code and show them what it does. If you don’t require a specific language/framework, then this is harder, but perhaps you could prepare more than one. We had both Objective-C and Swift versions of the interview app when Swift was still new.
  • Tell them what to expect beforehand. Before the interview, tell them exactly what the interview is going to be. “I will send you a project that does XXX using (language, framework, etc), you need XXX to run it, and then we’re going to add small features and do other things to it.”
  • Ask a question that makes them read the code. The first question should be to do something extremely easy with the code that makes them have to read a good portion of it.
  • Set an expectation that the code they write is a first draft, not production. Tell the candidate that this is “interview code”, not real production code, and we don’t have time to do everything that they would do. But, ask them to tell you what they would do if they had more time. If you want to see them do it (i.e. it’s part of the interview), ask them to do it—otherwise, consider it done.
  • Answer any question that they would normally google. Tell them that you don’t expect them to have memorized everything, so if they would normally google something, to just ask you and you will tell them. This is just to speed things up.
  • Remember that coding is one-dimension of the candidate. Being able to code is important, but it’s not the only thing that will determine success at the job. Pay close attention to collaboration and preparation (since you told them what to expect) and other aspects you find important.
  • Don’t treat the coding interview as a gate. If you give a coding interview first and immediately reject people, then you are going to miss out on a lot of good candidates. Make the goal to rate them on a few dimensions and pass them if they could do the job. Then, later in the process, compare the candidates on all dimensions of the job that you tested.

The goal of the technical interview is to find out if the person can do the coding aspects of the job. So, to the extent that you are doing what the job requires, the better the interview is at answering that question.

How to Become a 10x Programmer

The idea of the 10x programmer probably originated with Peopleware [amazon affiliate link]. The authors ran pairs of developers from the same organization through a “coding wars” exercise. They collected data from many organizations over several years and measured that the best coders did about 10x better than the worst and about 2.5x better than the median ones.

But, probably everything you have heard about what that means is wrong.

For one, even though the pairs did not work together at all, their results were highly correlated with each other. Secondly, the participants in the exercise worked at their desks in their normal working environment. Finally, there wasn’t a correlation to experience level or technology used.

The authors conclude that the organizational environment and culture is a major factor in the effectiveness of its programmers.

The bald fact is that many companies provide developers with a workplace that is so crowded, noisy, and interruptive as to fill their days with frustration. That alone could explain reduced efficiency as well as a tendency for good people to migrate elsewhere.

So, how do you become a 10x programmer? By changing jobs to an organization that provides an environment where you can be effective.

How Senior Software Developers Think

Senior Developers are expected to be more skilled in the technical aspects of software development. Just by having more years of experience they should be able to solve more problems, have more techniques, be faster, etc.

But, this alone is not enough to make them “senior” in my view. They will be more valuable than a junior developer doing tasks, but you can’t scale a team with a group of expert task doers.

The biggest differentiator between a junior developer and a more senior one is in the scope of their thinking and planning.

To keep it simple, imagine four levels of engineer (Jr, Dev, Sr, Lead). Here are some of the differences aside from programming skill. This distinction has nothing to do with people management—none of these levels have management responsibilities.

  1. Jr: Right out of school. Cannot do any task without some help. Can plan a couple of days of work.
  2. Dev: Can do most tasks independently. Can plan projects that take weeks to do.
  3. Sr: Takes product specs and writes functional/implementation specs and plans. Can plan projects that take months to do. Can coordinate the work of a team.
  4. Lead: Can plan projects that may take years. Thinks about overall architecture. Establishes processes. Can coordinate the work of multiple teams.

There is more to it than this, but the essence is increasing scope of time, planning, and coordination.

Another way to think of it is in what their goals are:

  1. Jr: Complete the ticket: e.g. Fix the bug, deploy the build
  2. Dev: Complete the project: e.g. Implement the export to CSV feature as specified
  3. Sr: Achieve the mission of the project/team: e.g. Increase paid conversion, reduce the crash rate
  4. Lead: Achieve the mission of the company: e.g. Increase profit margin by 10%, enter an adjacent market

To be fair, everyone should be working on the mission of the company. The difference is how they think about the work they are doing and how they evaluate success.

Tech Career Tip: Drive Revenue, Not Cost

I have spent most of my career in software product development, meaning the code I wrote went into the products that made money for the company I worked for. I did a short stint writing internal software for the organization itself and the difference was very stark to me.

When you write software for your organization, it’s often to automate something and the driver is cost-reduction. The problem is that cost can only be reduced so much and eventually you are one of the biggest costs (in a budget owned by someone who likes to cut).

Revenue, on the other hand, can be very outsized compared to your cost. The budgets for product development are often expressed as a percent of revenue, so success increases budgets.

And, often, product development jobs offer some way to participate in that upside (options, RSUs, etc). Getting equity from an IT developer isn’t as easy.

It’s more complex than just “for-sale” or “internal”. When I was in FinTech, I wrote products, but my peers at banks, writing internal software, certainly drove revenue for their employers and were paid very well through generous bonus systems.

Pay is not the most important benefit. When you are critical to how a company makes money, you have bigger growth opportunities, more respect, and generally more clout. Product developers at software product companies have career prospects that lead all the way to CEO. That is not often the case for developers automating internal operations.

Podcasts for Companion Learning

One of the advantages of podcasts is that they are audio-only, so you can listen to them while you do other things. I listen while doing chores, running, cooking, and driving. I mentioned in Soundtracks for Books that it’s hard to listen to something while you are doing effortful thinking.

But, just like a book soundtrack, you can pay attention to audio if the thing you are doing is really the same thing—something integrated with it.

I haven’t seen this much, but I think a big area for podcasts could be in guiding “learning by doing” tasks.

There are lots of video and text tutorials for learning programming. The issue is that you can be tempted to consume them without really doing the tasks yourself. And since you have to look at the book/video/blog etc, it’s hard to also be looking at your editor.

This kind of podcast could not just be played in your regular playlists though—you need to be at your computer ready to listen. It could guide you in a vague way, so that you have to think in order to do the tasks, not just listen while you exercise.

I’m not sure that a programming guide podcast is a good fit for very new learners, who still need a lot of help with the syntax. It would be better for learners who can write lines of code syntactically correct from a short-hand description.

Like I said in Vague Tutorials Would Help with Coding Interviews, I think getting good at taking spoken directions would help in coding interviews.

A Cover Letter is an Argument

A few days ago I wrote that your resumé should make no sense, where I explained that you should customize your resumé so that it is tailored to the receiver to such a degree that sending it to anyone else would make no sense.

A cover letter is similarly customized, but I think that’s more obvious. Never use a generic cover letter. If the application is cold, you need all the help you can get. If it’s not, for example, if you are being referred, then you really need to mention that.

The cover letter is a response to the job description. It is a point-by-point argument for why you are best person for the job as it was described. It is a guide for navigating the resumé. It is a writing sample. Every job description asks us to have excellent communication skills. Your cover letter is the way you prove this.

Before you even start to write it, you need to dissect the job description and pull out the most important asks where you have an excellent response. If you don’t have an excellent response, this might not be the job to apply for.

You will also have one or two things about you that are so great, that you need to get them in the letter. This could be a side-project or open-source contribution, a talk you gave at a conference, some technical achievement at work.

Finally, you should research the company enough to try to find other things that would make you a good fit. Read the company blog or twitter. Get a sense of who they are. If the company is small, you might be able to find team members or the hiring manager of the job they are looking to fill.

With all of this raw material, write a letter that makes it clear that

  1. You are specifically trying to get this job, not any job
  2. You are willing to put in work to get it
  3. You have the required skills of the job
  4. You have excellent communication skills

From experience I can tell you that getting one like this is rare. When I am the one filtering the pile, I will always call anyone that does this and give them a chance.

I got my last two jobs with cold applications and extremely custom letters. Of course, the letter just gets you the interview, but you are going to do a similar amount of preparation for those as well.

Your Resumé Should Make no Sense

If you sending out resumés and getting auto-rejected or never even contacted, let me help you understand why.

Yesterday, I wrote about writing a Job Statement, which is a very specific description of the job you want. You can think of it as the employee equivalent of an employer’s job description.

You are now looking for something very specific. And when you find one to apply to, you are also a very specific person.

So, why is your resumé generic? If you could send this same resumé to lots of different software developer jobs, then it’s going to get filtered out for a lot of them.

Consider the receiver. If this is a well-known company who will get a lot of applicants, they may get a hundred applicants to every position. I worked for small companies in small job markets and could get that sometimes (especially when we targeted new grads at the local colleges).

With such a pile, the reader has no choice but to skim each quickly. Imagine that they will read the very first lines and then skim for a few pieces of key information. If you pass that, they might give it a more careful read. It is also possible that they are using crappy software to score the resumé ahead of time.

Why will your application get chosen?

Here’s one way. Your resumé should be so specifically meant for that job that it would make no sense to send it to anyone else.

Doing this takes a little longer than just spamming job sites with your generic resumé, but the hit rate is worth it. And it’s really not that bad. You are going to start from a long generic resumé and edit it to be more focussed. I personally maintain a few styles because I have more than one domain I am willing to work in (and they are different enough to warrant this).

Read the job description very carefully and figure out the one or two most important things they are looking for. Take note of the words they use, especially jargon or technical terms, because you will use them as well.

The very first real sentence of the resumé, below your contact info, should be a concise argument for why you should be hired for this specific job hitting those two most important points.

Next, should be a concise summary of your technical qualifications, edited to be specific to this job. Maybe label this section “Relevant Skills” if you are afraid you are editing it down too much.

In every job you list, make sure the reader can skim and see the tech stack you used there (bold it). Use the job description as a guide to what you write about the job.

The description of your current job should be very specifically tailored for this receiver, and you can do this to a lesser extent as you go through the resumé (but it won’t hurt to do it completely).

If you need help, please get in touch.

Your cover letter is going to be even more customized. I’ll cover that soon.

Note: If you think your resumé will be auto-scored, the standard recommendation is to make sure your resumé has the keywords they are looking for. Since you are tailoring the it to the job description, you should be fine.