Like most startups, we get a lot of resumes, and we spend a lot of our time reading them. But no matter how much time we spend in aggregate, we only have a few minutes to go over any particular resume. After reading hundreds of resumes and interviewing dozens of people, we’ve gotten a pretty good sense of who will work out.
And who will not.
One of the top things we look at, both when reading resumes and when interviewing, is communication skills. We’ve talked to many folks who were clearly bright, but whose lack of ability to communicate tanked their interviews. In fact, lack of communication skills is probably equal to lack of technical competence in terms of driving rejections..
One of the most egregious offenders at the resume review step is overly long resumes. These are one of the clearest indicators of lack of communication skills: A single page for every five years of experience tends to be plenty. Can’t do it? Then your communication skills may need some polishing. At in-person interviews we see the same issues as well – candidates who do not take time to make sure that they understand problems posed to them, who do not ask clarifying questions, who do not explain their thought process when solving problems, who ramble for minutes rather than answering a question succinctly. In a small, highly collaborative company, folks who cannot communicate are hamstrung in their ability to influence, their ability to solve problems in a timely manner, their ability to deliver code that matches requirements.
We dream of a new kind of resume – one that is clean, and clear, and free of technical jargon. One that communicates passion and aptitude, energy and enthusiasm, intelligence and sociability. The usual resume template of “here is where and when I worked and what my title was and what technologies were involved” is a poor communicator. What about resumes that speak to a person’s true career development?
For example, a timeline of technical maturity, with location of employment as a secondary concern? After all, if you’ve worked at one company for 10 years but grew constantly, why should that take as much space as a position where you worked for only 1 year?
So we lay down this challenge – rethink your resume, send us something original, something more than simply where you worked and what you know! Something that communicates who you are, and what you are about.
We look forward to hearing from you.
We planted some tomatoes on our deck last week:
We came back from the July 4th weekend to some significant progress. We figure we’re getting about 2″ of growth per day – the weather here in San Mateo has been amazing.
To close out the discussion on SOLID, the D in SOLID stands for “Dependency Inversion” and is currently a bit of a darling in the industry, with significant efforts from many communities and companies to provide infrastructure that allows developers to implement this practice.
Now, dependency inversion does not require an inversion of control container, nor does it even imply that one must use dependency injection. These patterns are natural outcomes of this principal, that states that components should not depend upon concrete implementations, but on abstractions. More concretely, and often, that components should not depend on classes, but on interfaces.
The most powerful example of how this principal can help companies scale is in unit test suites: In a company that I’ve worked at previously, which built on of the world’s biggest applications, running regression tests on even a tiny part of the system could take days, and entire labs and teams were responsible for test execution and reporting. Startups simply cannot afford this kind of overhead (arguably, these days, no one can afford this kind of overhead.) The requirement for tests to run fast is a matter of survival. So consider the example of a startup, such as Sociable Labs, that is hosted in the cloud (Amazon, in our case) and makes use of many cloud services – key stores, binary storage systems, databases, distributed queues, Facebook’s Open Graph, the Twitter API, and much more. Now imagine running a full regression suite that runs thousands of tests against all of these systems. It would, and does, take hours to days, and new tests are constantly being added.
In order to be able to regression test our own systems independent of all of these systems, we provide mock implementations of all of the above services: We have mock Facebook implementations, mock S3 implementations, mocks of the database repositories and of our configuration server. In order to be able to tell our code to use these mocks, the code must not rely on any concrete implementations of S3 or Facebook clients – they must rely on interfaces so that we can provide one implementation at unit test time, and another during full regression passes or in production.
There are many systems that enable this sort of configuration, and most come down to some central authority, such as a service locator or container, which is configured via some mechanism so that it knows what concrete implementation to provide for a particular interface.
As an interesting aside, the classic Singleton pattern can easily become a massive source of violations of this principal. We use a combination of the service locator pattern and inversion of control to give our developers a very clean, intuitive view of the system that is actually more convenient and simple than the Singleton pattern, but without that pattern’s hard dependency code smell.
The I in SOLID stands for “Interface Segregation” and is a hallmark of high quality, disciplined framework design: As system requirements change over time, there is often the temptation to short-circuit codepaths, to add just one more API to some class to make things just work. This is one of the ways in which code rot enters systems: One boundaries and responsibilities of systems are not clear, there is momentum towards tighter coupling/more brittleness in the system.
Interface segregation is something of a special case of single responsibility: An interface tells us that an object supports a certain set of operations, and interface segregation adds that that set of operations must have a maximal degree of cohesion. For example, an interface such as IObjectCache should really only have three methods: add, get, remove. It is tempting to start growing this interface, to add methods such as queryKeys, and getStatistics, increment, decrement, push and pop. As we add new methods, the interface becomes harder and harder for new implementations to support, and so decreases the usefulness of the interface. Breaking that interface down into a hierarchy allows classes to implement more or less capabilities, and clients to more clearly declare which particular set of capabilities they need. Goodness all around.
Innovation will make or break a startup like Sociable Labs: We have to keep up with what is going on in the Social world on the technological, psychological, social, and business fronts, and then quickly apply new capabilities and patterns to help our customers and move our platform forward.
Transforming knowledge into innovation is something we think about a lot, and not just at a subconscious level: We apply a number of techniques, one of the most powerful of which is inversion.
To understand the power of inversion, consider a few different examples: In the business space, consider the traditional auction in which users bid the price of a product up. The technique of inversion involves looking for vectors of action or design and inverting them. In this case, we see a clear and simple vector where prices are being bid up. What if we invert that and bid prices down? In that case, we get reverse auctions, which are a powerful and useful variant. Let’s find another opportunity for inversion: What if we inverted the role of the buyer into a seller, and set up a barter system where sellers could join together to exchange goods via an offer system?
Another interesting recent example in the education space is the inversion of homework and schooling – an experiment where students do their homework in school, and study at home. An approach that has, apparently, shown some promise.
In the technology world, there are great examples of powerful inversions: For example, the idea of inversion of control, where systems do not directly go and find other systems (e.g. a CRM system going out to find an email system to send notifications) but are wired together by an external agent. Another example is the idea of using the shape of the tables in a database to generate classes for an application. Inverting this would say that we should use the shape of classes to generate databases, and indeed both patterns are useful and present in the industry.
Sometimes though, one vector of approach does not work well, but its inversion does. For example, we have not seen immense success in bringing companies’ commerce systems to Facebook applications, but inverting that and bringing Facebook’s Open Graph to companies’ commerce sites has worked amazingly well.
As we experiment and develop new systems and solutions, we always try to look at a variety of inversions in order to see if we have covered possibility space in a thorough way. We hope this technique helps you generate new ideas.
- By “meaningful”, we mean those questions that tell us what our risks are for any action: Schedule risk, quality risk, customer risk.
- By “iterative”, we mean that processes are constantly being tuned to better answer questions.